ActivityManagerService.java revision c6f9c85f746d72a54737f8e714b190939561c28b
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.BIND_VOICE_INTERACTION;
20import static android.Manifest.permission.CHANGE_CONFIGURATION;
21import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
22import static android.Manifest.permission.INTERACT_ACROSS_USERS;
23import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
24import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
25import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
26import static android.Manifest.permission.READ_FRAME_BUFFER;
27import static android.Manifest.permission.REMOVE_TASKS;
28import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
29import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
30import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
31import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
32import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
33import static android.app.ActivityManagerInternal.ASSIST_KEY_CONTENT;
34import static android.app.ActivityManagerInternal.ASSIST_KEY_DATA;
35import static android.app.ActivityManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
36import static android.app.ActivityManagerInternal.ASSIST_KEY_STRUCTURE;
37import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
38import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE;
39import static android.app.AppOpsManager.OP_NONE;
40import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
41import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
42import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
43import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
44import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
45import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
46import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
47import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
48import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
49import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
50import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
51import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
52import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
53import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
54import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
55import static android.content.pm.PackageManager.GET_PROVIDERS;
56import static android.content.pm.PackageManager.MATCH_ANY_USER;
57import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
58import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
59import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
60import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
61import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
62import static android.content.pm.PackageManager.PERMISSION_GRANTED;
63import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
64import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
65import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
66import static android.os.Build.VERSION_CODES.N;
67import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
68import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
69import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
70import static android.os.IServiceManager.DUMP_FLAG_PROTO;
71import static android.os.Process.BLUETOOTH_UID;
72import static android.os.Process.FIRST_APPLICATION_UID;
73import static android.os.Process.FIRST_ISOLATED_UID;
74import static android.os.Process.LAST_ISOLATED_UID;
75import static android.os.Process.NFC_UID;
76import static android.os.Process.PHONE_UID;
77import static android.os.Process.PROC_CHAR;
78import static android.os.Process.PROC_OUT_LONG;
79import static android.os.Process.PROC_PARENS;
80import static android.os.Process.PROC_SPACE_TERM;
81import static android.os.Process.ProcessStartResult;
82import static android.os.Process.ROOT_UID;
83import static android.os.Process.SCHED_FIFO;
84import static android.os.Process.SCHED_OTHER;
85import static android.os.Process.SCHED_RESET_ON_FORK;
86import static android.os.Process.SHELL_UID;
87import static android.os.Process.SIGNAL_QUIT;
88import static android.os.Process.SIGNAL_USR1;
89import static android.os.Process.SYSTEM_UID;
90import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
91import static android.os.Process.THREAD_GROUP_DEFAULT;
92import static android.os.Process.THREAD_GROUP_TOP_APP;
93import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
94import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
95import static android.os.Process.getFreeMemory;
96import static android.os.Process.getTotalMemory;
97import static android.os.Process.isThreadInProcess;
98import static android.os.Process.killProcess;
99import static android.os.Process.killProcessQuiet;
100import static android.os.Process.myPid;
101import static android.os.Process.myUid;
102import static android.os.Process.readProcFile;
103import static android.os.Process.removeAllProcessGroups;
104import static android.os.Process.sendSignal;
105import static android.os.Process.setProcessGroup;
106import static android.os.Process.setThreadPriority;
107import static android.os.Process.setThreadScheduler;
108import static android.os.Process.startWebView;
109import static android.os.Process.zygoteProcess;
110import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
111import static android.provider.Settings.Global.DEBUG_APP;
112import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
113import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
114import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
115import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
116import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
117import static android.provider.Settings.System.FONT_SCALE;
118import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
119import static android.text.format.DateUtils.DAY_IN_MILLIS;
120import static android.view.Display.DEFAULT_DISPLAY;
121import static android.view.Display.INVALID_DISPLAY;
122import static com.android.internal.util.XmlUtils.readBooleanAttribute;
123import static com.android.internal.util.XmlUtils.readIntAttribute;
124import static com.android.internal.util.XmlUtils.readLongAttribute;
125import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
126import static com.android.internal.util.XmlUtils.writeIntAttribute;
127import static com.android.internal.util.XmlUtils.writeLongAttribute;
128import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
141import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
142import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
143import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
144import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
145import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
146import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
147import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
148import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
149import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
150import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
151import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
152import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
153import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
154import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
155import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
156import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
157import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
158import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
159import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
160import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
161import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
162import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
163import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
164import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
165import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
166import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
167import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
168import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
169import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
170import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
171import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
172import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
173import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
174import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
175import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
176import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
177import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
178import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
179import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
180import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
181import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
182import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
183import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
184import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
185import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
186import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
187import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
188import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
189import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
190import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
191import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
192import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
193import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
194import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
195import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
196import static com.android.server.wm.AppTransition.TRANSIT_NONE;
197import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
198import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
199import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
200import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
201import static org.xmlpull.v1.XmlPullParser.START_TAG;
202
203import android.Manifest;
204import android.Manifest.permission;
205import android.annotation.NonNull;
206import android.annotation.Nullable;
207import android.annotation.UserIdInt;
208import android.app.Activity;
209import android.app.ActivityManager;
210import android.app.ActivityManager.RunningTaskInfo;
211import android.app.ActivityManager.StackInfo;
212import android.app.ActivityManager.TaskSnapshot;
213import android.app.ActivityManagerInternal;
214import android.app.ActivityManagerInternal.ScreenObserver;
215import android.app.ActivityManagerInternal.SleepToken;
216import android.app.ActivityOptions;
217import android.app.ActivityThread;
218import android.app.AlertDialog;
219import android.app.AppGlobals;
220import android.app.AppOpsManager;
221import android.app.ApplicationErrorReport;
222import android.app.ApplicationThreadConstants;
223import android.app.BroadcastOptions;
224import android.app.ContentProviderHolder;
225import android.app.Dialog;
226import android.app.IActivityController;
227import android.app.IActivityManager;
228import android.app.IApplicationThread;
229import android.app.IAssistDataReceiver;
230import android.app.IInstrumentationWatcher;
231import android.app.INotificationManager;
232import android.app.IProcessObserver;
233import android.app.IServiceConnection;
234import android.app.IStopUserCallback;
235import android.app.ITaskStackListener;
236import android.app.IUiAutomationConnection;
237import android.app.IUidObserver;
238import android.app.IUserSwitchObserver;
239import android.app.Instrumentation;
240import android.app.Notification;
241import android.app.NotificationManager;
242import android.app.PendingIntent;
243import android.app.PictureInPictureParams;
244import android.app.ProfilerInfo;
245import android.app.RemoteAction;
246import android.app.WaitResult;
247import android.app.WindowConfiguration.ActivityType;
248import android.app.WindowConfiguration.WindowingMode;
249import android.app.admin.DevicePolicyManager;
250import android.app.assist.AssistContent;
251import android.app.assist.AssistStructure;
252import android.app.backup.IBackupManager;
253import android.app.servertransaction.ConfigurationChangeItem;
254import android.app.usage.UsageEvents;
255import android.app.usage.UsageStatsManagerInternal;
256import android.appwidget.AppWidgetManager;
257import android.content.ActivityNotFoundException;
258import android.content.BroadcastReceiver;
259import android.content.ClipData;
260import android.content.ComponentCallbacks2;
261import android.content.ComponentName;
262import android.content.ContentProvider;
263import android.content.ContentResolver;
264import android.content.Context;
265import android.content.DialogInterface;
266import android.content.IContentProvider;
267import android.content.IIntentReceiver;
268import android.content.IIntentSender;
269import android.content.Intent;
270import android.content.IntentFilter;
271import android.content.pm.ActivityInfo;
272import android.content.pm.ApplicationInfo;
273import android.content.pm.ConfigurationInfo;
274import android.content.pm.IPackageDataObserver;
275import android.content.pm.IPackageManager;
276import android.content.pm.InstrumentationInfo;
277import android.content.pm.PackageInfo;
278import android.content.pm.PackageManager;
279import android.content.pm.PackageManagerInternal;
280import android.content.pm.PackageManager.NameNotFoundException;
281import android.content.pm.ParceledListSlice;
282import android.content.pm.PathPermission;
283import android.content.pm.PermissionInfo;
284import android.content.pm.ProviderInfo;
285import android.content.pm.ResolveInfo;
286import android.content.pm.SELinuxUtil;
287import android.content.pm.ServiceInfo;
288import android.content.pm.UserInfo;
289import android.content.res.CompatibilityInfo;
290import android.content.res.Configuration;
291import android.content.res.Resources;
292import android.database.ContentObserver;
293import android.graphics.Bitmap;
294import android.graphics.Point;
295import android.graphics.Rect;
296import android.location.LocationManager;
297import android.media.audiofx.AudioEffect;
298import android.metrics.LogMaker;
299import android.net.Proxy;
300import android.net.ProxyInfo;
301import android.net.Uri;
302import android.os.BatteryStats;
303import android.os.Binder;
304import android.os.Build;
305import android.os.Bundle;
306import android.os.Debug;
307import android.os.DropBoxManager;
308import android.os.Environment;
309import android.os.FactoryTest;
310import android.os.FileObserver;
311import android.os.FileUtils;
312import android.os.Handler;
313import android.os.IBinder;
314import android.os.IDeviceIdentifiersPolicyService;
315import android.os.IPermissionController;
316import android.os.IProcessInfoService;
317import android.os.IProgressListener;
318import android.os.LocaleList;
319import android.os.Looper;
320import android.os.Message;
321import android.os.Parcel;
322import android.os.ParcelFileDescriptor;
323import android.os.PersistableBundle;
324import android.os.PowerManager;
325import android.os.PowerManager.ServiceType;
326import android.os.PowerManagerInternal;
327import android.os.Process;
328import android.os.RemoteCallbackList;
329import android.os.RemoteException;
330import android.os.ResultReceiver;
331import android.os.ServiceManager;
332import android.os.ShellCallback;
333import android.os.StrictMode;
334import android.os.SystemClock;
335import android.os.SystemProperties;
336import android.os.Trace;
337import android.os.TransactionTooLargeException;
338import android.os.UpdateLock;
339import android.os.UserHandle;
340import android.os.UserManager;
341import android.os.WorkSource;
342import android.os.storage.IStorageManager;
343import android.os.storage.StorageManager;
344import android.os.storage.StorageManagerInternal;
345import android.provider.Downloads;
346import android.provider.Settings;
347import android.service.voice.IVoiceInteractionSession;
348import android.service.voice.VoiceInteractionManagerInternal;
349import android.telecom.TelecomManager;
350import android.text.TextUtils;
351import android.text.format.DateUtils;
352import android.text.format.Time;
353import android.text.style.SuggestionSpan;
354import android.util.ArrayMap;
355import android.util.ArraySet;
356import android.util.AtomicFile;
357import android.util.LongSparseArray;
358import android.util.StatsLog;
359import android.util.TimingsTraceLog;
360import android.util.DebugUtils;
361import android.util.EventLog;
362import android.util.Log;
363import android.util.Pair;
364import android.util.PrintWriterPrinter;
365import android.util.Slog;
366import android.util.SparseArray;
367import android.util.SparseIntArray;
368import android.util.TimeUtils;
369import android.util.Xml;
370import android.util.proto.ProtoOutputStream;
371import android.view.Gravity;
372import android.view.LayoutInflater;
373import android.view.View;
374import android.view.WindowManager;
375
376import com.android.internal.R;
377import com.android.internal.annotations.GuardedBy;
378import com.android.internal.annotations.VisibleForTesting;
379import com.android.internal.app.AssistUtils;
380import com.android.internal.app.DumpHeapActivity;
381import com.android.internal.app.IAppOpsCallback;
382import com.android.internal.app.IAppOpsService;
383import com.android.internal.app.IVoiceInteractor;
384import com.android.internal.app.ProcessMap;
385import com.android.internal.app.SystemUserHomeActivity;
386import com.android.internal.app.procstats.ProcessStats;
387import com.android.internal.logging.MetricsLogger;
388import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
389import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
390import com.android.internal.notification.SystemNotificationChannels;
391import com.android.internal.os.BackgroundThread;
392import com.android.internal.os.BatteryStatsImpl;
393import com.android.internal.os.BinderInternal;
394import com.android.internal.os.ByteTransferPipe;
395import com.android.internal.os.IResultReceiver;
396import com.android.internal.os.ProcessCpuTracker;
397import com.android.internal.os.TransferPipe;
398import com.android.internal.os.Zygote;
399import com.android.internal.policy.IKeyguardDismissCallback;
400import com.android.internal.telephony.TelephonyIntents;
401import com.android.internal.util.ArrayUtils;
402import com.android.internal.util.DumpUtils;
403import com.android.internal.util.FastPrintWriter;
404import com.android.internal.util.FastXmlSerializer;
405import com.android.internal.util.MemInfoReader;
406import com.android.internal.util.Preconditions;
407import com.android.server.AlarmManagerInternal;
408import com.android.server.AppOpsService;
409import com.android.server.AttributeCache;
410import com.android.server.DeviceIdleController;
411import com.android.server.IntentResolver;
412import com.android.server.IoThread;
413import com.android.server.LocalServices;
414import com.android.server.LockGuard;
415import com.android.server.NetworkManagementInternal;
416import com.android.server.RescueParty;
417import com.android.server.ServiceThread;
418import com.android.server.SystemConfig;
419import com.android.server.SystemService;
420import com.android.server.SystemServiceManager;
421import com.android.server.ThreadPriorityBooster;
422import com.android.server.Watchdog;
423import com.android.server.am.ActivityStack.ActivityState;
424import com.android.server.am.EventLogTags;
425import com.android.server.am.proto.ActivityManagerServiceProto;
426import com.android.server.am.proto.BroadcastProto;
427import com.android.server.am.proto.GrantUriProto;
428import com.android.server.am.proto.MemInfoProto;
429import com.android.server.am.proto.NeededUriGrantsProto;
430import com.android.server.am.proto.StickyBroadcastProto;
431import com.android.server.firewall.IntentFirewall;
432import com.android.server.job.JobSchedulerInternal;
433import com.android.server.pm.Installer;
434import com.android.server.pm.Installer.InstallerException;
435import com.android.server.utils.PriorityDump;
436import com.android.server.vr.VrManagerInternal;
437import com.android.server.wm.PinnedStackWindowController;
438import com.android.server.wm.WindowManagerService;
439import com.google.android.collect.Lists;
440import com.google.android.collect.Maps;
441
442import org.xmlpull.v1.XmlPullParser;
443import org.xmlpull.v1.XmlPullParserException;
444import org.xmlpull.v1.XmlSerializer;
445
446import java.io.File;
447import java.io.FileDescriptor;
448import java.io.FileInputStream;
449import java.io.FileNotFoundException;
450import java.io.FileOutputStream;
451import java.io.IOException;
452import java.io.InputStreamReader;
453import java.io.PrintWriter;
454import java.io.StringWriter;
455import java.io.UnsupportedEncodingException;
456import java.lang.ref.WeakReference;
457import java.nio.charset.StandardCharsets;
458import java.text.DateFormat;
459import java.text.SimpleDateFormat;
460import java.util.ArrayList;
461import java.util.Arrays;
462import java.util.Collections;
463import java.util.Comparator;
464import java.util.Date;
465import java.util.HashMap;
466import java.util.HashSet;
467import java.util.Iterator;
468import java.util.List;
469import java.util.Locale;
470import java.util.Map;
471import java.util.Objects;
472import java.util.Set;
473import java.util.concurrent.CountDownLatch;
474import java.util.concurrent.atomic.AtomicBoolean;
475import java.util.concurrent.atomic.AtomicLong;
476
477import dalvik.system.VMRuntime;
478
479import libcore.io.IoUtils;
480import libcore.util.EmptyArray;
481
482public class ActivityManagerService extends IActivityManager.Stub
483        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
484
485    /**
486     * Priority we boost main thread and RT of top app to.
487     */
488    public static final int TOP_APP_PRIORITY_BOOST = -10;
489
490    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
491    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
492    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
493    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
494    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
495    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
496    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
497    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
498    private static final String TAG_LRU = TAG + POSTFIX_LRU;
499    private static final String TAG_MU = TAG + POSTFIX_MU;
500    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
501    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
502    private static final String TAG_POWER = TAG + POSTFIX_POWER;
503    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
504    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
505    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
506    private static final String TAG_PSS = TAG + POSTFIX_PSS;
507    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
508    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
509    private static final String TAG_STACK = TAG + POSTFIX_STACK;
510    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
511    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
512    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
513    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
514
515    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
516    // here so that while the job scheduler can depend on AMS, the other way around
517    // need not be the case.
518    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
519
520    /** Control over CPU and battery monitoring */
521    // write battery stats every 30 minutes.
522    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
523    static final boolean MONITOR_CPU_USAGE = true;
524    // don't sample cpu less than every 5 seconds.
525    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
526    // wait possibly forever for next cpu sample.
527    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
528    static final boolean MONITOR_THREAD_CPU_USAGE = false;
529
530    // The flags that are set for all calls we make to the package manager.
531    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
532
533    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
534
535    // Amount of time after a call to stopAppSwitches() during which we will
536    // prevent further untrusted switches from happening.
537    static final long APP_SWITCH_DELAY_TIME = 5*1000;
538
539    // How long we wait for a launched process to attach to the activity manager
540    // before we decide it's never going to come up for real.
541    static final int PROC_START_TIMEOUT = 10*1000;
542    // How long we wait for an attached process to publish its content providers
543    // before we decide it must be hung.
544    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
545
546    // How long we wait for a launched process to attach to the activity manager
547    // before we decide it's never going to come up for real, when the process was
548    // started with a wrapper for instrumentation (such as Valgrind) because it
549    // could take much longer than usual.
550    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
551
552    // How long we allow a receiver to run before giving up on it.
553    static final int BROADCAST_FG_TIMEOUT = 10*1000;
554    static final int BROADCAST_BG_TIMEOUT = 60*1000;
555
556    // How long we wait until we timeout on key dispatching.
557    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
558
559    // How long we wait until we timeout on key dispatching during instrumentation.
560    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
561
562    // How long to wait in getAssistContextExtras for the activity and foreground services
563    // to respond with the result.
564    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
565
566    // How long top wait when going through the modern assist (which doesn't need to block
567    // on getting this result before starting to launch its UI).
568    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
569
570    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
571    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
572
573    // Maximum number of persisted Uri grants a package is allowed
574    static final int MAX_PERSISTED_URI_GRANTS = 128;
575
576    static final int MY_PID = myPid();
577
578    static final String[] EMPTY_STRING_ARRAY = new String[0];
579
580    // How many bytes to write into the dropbox log before truncating
581    static final int DROPBOX_MAX_SIZE = 192 * 1024;
582    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
583    // as one line, but close enough for now.
584    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
585
586    // Access modes for handleIncomingUser.
587    static final int ALLOW_NON_FULL = 0;
588    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
589    static final int ALLOW_FULL_ONLY = 2;
590
591    // Necessary ApplicationInfo flags to mark an app as persistent
592    private static final int PERSISTENT_MASK =
593            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
594
595    // Intent sent when remote bugreport collection has been completed
596    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
597            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
598
599    // Used to indicate that an app transition should be animated.
600    static final boolean ANIMATE = true;
601
602    // Determines whether to take full screen screenshots
603    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
604
605    /**
606     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
607     */
608    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
609
610    /**
611     * State indicating that there is no need for any blocking for network.
612     */
613    @VisibleForTesting
614    static final int NETWORK_STATE_NO_CHANGE = 0;
615
616    /**
617     * State indicating that the main thread needs to be informed about the network wait.
618     */
619    @VisibleForTesting
620    static final int NETWORK_STATE_BLOCK = 1;
621
622    /**
623     * State indicating that any threads waiting for network state to get updated can be unblocked.
624     */
625    @VisibleForTesting
626    static final int NETWORK_STATE_UNBLOCK = 2;
627
628    // Max character limit for a notification title. If the notification title is larger than this
629    // the notification will not be legible to the user.
630    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
631
632    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
633
634    /** All system services */
635    SystemServiceManager mSystemServiceManager;
636
637    // Wrapper around VoiceInteractionServiceManager
638    private AssistUtils mAssistUtils;
639
640    // Keeps track of the active voice interaction service component, notified from
641    // VoiceInteractionManagerService
642    ComponentName mActiveVoiceInteractionServiceComponent;
643
644    private Installer mInstaller;
645
646    /** Run all ActivityStacks through this */
647    final ActivityStackSupervisor mStackSupervisor;
648    private final KeyguardController mKeyguardController;
649
650    private final ActivityStartController mActivityStartController;
651
652    final ClientLifecycleManager mLifecycleManager;
653
654    final TaskChangeNotificationController mTaskChangeNotificationController;
655
656    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
657
658    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
659
660    public final IntentFirewall mIntentFirewall;
661
662    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
663    // default action automatically.  Important for devices without direct input
664    // devices.
665    private boolean mShowDialogs = true;
666
667    private final VrController mVrController;
668
669    // VR Vr2d Display Id.
670    int mVr2dDisplayId = INVALID_DISPLAY;
671
672    // Whether we should use SCHED_FIFO for UI and RenderThreads.
673    private boolean mUseFifoUiScheduling = false;
674
675    BroadcastQueue mFgBroadcastQueue;
676    BroadcastQueue mBgBroadcastQueue;
677    // Convenient for easy iteration over the queues. Foreground is first
678    // so that dispatch of foreground broadcasts gets precedence.
679    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
680
681    BroadcastStats mLastBroadcastStats;
682    BroadcastStats mCurBroadcastStats;
683
684    BroadcastQueue broadcastQueueForIntent(Intent intent) {
685        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
686        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
687                "Broadcast intent " + intent + " on "
688                + (isFg ? "foreground" : "background") + " queue");
689        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
690    }
691
692    /**
693     * The last resumed activity. This is identical to the current resumed activity most
694     * of the time but could be different when we're pausing one activity before we resume
695     * another activity.
696     */
697    private ActivityRecord mLastResumedActivity;
698
699    /**
700     * If non-null, we are tracking the time the user spends in the currently focused app.
701     */
702    private AppTimeTracker mCurAppTimeTracker;
703
704    /**
705     * List of intents that were used to start the most recent tasks.
706     */
707    private final RecentTasks mRecentTasks;
708
709    /**
710     * For addAppTask: cached of the last activity component that was added.
711     */
712    ComponentName mLastAddedTaskComponent;
713
714    /**
715     * For addAppTask: cached of the last activity uid that was added.
716     */
717    int mLastAddedTaskUid;
718
719    /**
720     * For addAppTask: cached of the last ActivityInfo that was added.
721     */
722    ActivityInfo mLastAddedTaskActivity;
723
724    /**
725     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
726     */
727    String mDeviceOwnerName;
728
729    /**
730     * The controller for all operations related to locktask.
731     */
732    final LockTaskController mLockTaskController;
733
734    final UserController mUserController;
735
736    /**
737     * Packages that are being allowed to perform unrestricted app switches.  Mapping is
738     * User -> Type -> uid.
739     */
740    final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
741
742    final AppErrors mAppErrors;
743
744    final AppWarnings mAppWarnings;
745
746    /**
747     * Dump of the activity state at the time of the last ANR. Cleared after
748     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
749     */
750    String mLastANRState;
751
752    /**
753     * Indicates the maximum time spent waiting for the network rules to get updated.
754     */
755    @VisibleForTesting
756    long mWaitForNetworkTimeoutMs;
757
758    /**
759     * Helper class which parses out priority arguments and dumps sections according to their
760     * priority. If priority arguments are omitted, function calls the legacy dump command.
761     */
762    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
763        @Override
764        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
765                boolean asProto) {
766            if (asProto) return;
767            doDump(fd, pw, new String[]{"activities"}, asProto);
768        }
769
770        @Override
771        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
772            if (asProto) {
773                doDump(fd, pw, new String[0], asProto);
774            } else {
775                doDump(fd, pw, new String[]{"settings"}, asProto);
776                doDump(fd, pw, new String[]{"intents"}, asProto);
777                doDump(fd, pw, new String[]{"broadcasts"}, asProto);
778                doDump(fd, pw, new String[]{"providers"}, asProto);
779                doDump(fd, pw, new String[]{"permissions"}, asProto);
780                doDump(fd, pw, new String[]{"services"}, asProto);
781                doDump(fd, pw, new String[]{"recents"}, asProto);
782                doDump(fd, pw, new String[]{"lastanr"}, asProto);
783                doDump(fd, pw, new String[]{"starter"}, asProto);
784                if (mAssociations.size() > 0) {
785                    doDump(fd, pw, new String[]{"associations"}, asProto);
786                }
787                doDump(fd, pw, new String[]{"processes"}, asProto);
788            }
789        }
790
791        @Override
792        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
793            doDump(fd, pw, args, asProto);
794        }
795    };
796
797    public boolean canShowErrorDialogs() {
798        return mShowDialogs && !mSleeping && !mShuttingDown
799                && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
800                && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
801                        mUserController.getCurrentUserId())
802                && !(UserManager.isDeviceInDemoMode(mContext)
803                        && mUserController.getCurrentUser().isDemo());
804    }
805
806    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
807            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
808
809    static void boostPriorityForLockedSection() {
810        sThreadPriorityBooster.boost();
811    }
812
813    static void resetPriorityAfterLockedSection() {
814        sThreadPriorityBooster.reset();
815    }
816
817    public class PendingAssistExtras extends Binder implements Runnable {
818        public final ActivityRecord activity;
819        public boolean isHome;
820        public final Bundle extras;
821        public final Intent intent;
822        public final String hint;
823        public final IAssistDataReceiver receiver;
824        public final int userHandle;
825        public boolean haveResult = false;
826        public Bundle result = null;
827        public AssistStructure structure = null;
828        public AssistContent content = null;
829        public Bundle receiverExtras;
830
831        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
832                String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
833                int _userHandle) {
834            activity = _activity;
835            extras = _extras;
836            intent = _intent;
837            hint = _hint;
838            receiver = _receiver;
839            receiverExtras = _receiverExtras;
840            userHandle = _userHandle;
841        }
842
843        @Override
844        public void run() {
845            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
846            synchronized (this) {
847                haveResult = true;
848                notifyAll();
849            }
850            pendingAssistExtrasTimedOut(this);
851        }
852    }
853
854    final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
855
856    /**
857     * Process management.
858     */
859    final ProcessList mProcessList = new ProcessList();
860
861    /**
862     * All of the applications we currently have running organized by name.
863     * The keys are strings of the application package name (as
864     * returned by the package manager), and the keys are ApplicationRecord
865     * objects.
866     */
867    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
868
869    /**
870     * Tracking long-term execution of processes to look for abuse and other
871     * bad app behavior.
872     */
873    final ProcessStatsService mProcessStats;
874
875    /**
876     * The currently running isolated processes.
877     */
878    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
879
880    /**
881     * Counter for assigning isolated process uids, to avoid frequently reusing the
882     * same ones.
883     */
884    int mNextIsolatedProcessUid = 0;
885
886    /**
887     * The currently running heavy-weight process, if any.
888     */
889    ProcessRecord mHeavyWeightProcess = null;
890
891    /**
892     * Non-persistent appId whitelist for background restrictions
893     */
894    int[] mBackgroundAppIdWhitelist = new int[] {
895            BLUETOOTH_UID
896    };
897
898    /**
899     * Broadcast actions that will always be deliverable to unlaunched/background apps
900     */
901    ArraySet<String> mBackgroundLaunchBroadcasts;
902
903    /**
904     * All of the processes we currently have running organized by pid.
905     * The keys are the pid running the application.
906     *
907     * <p>NOTE: This object is protected by its own lock, NOT the global
908     * activity manager lock!
909     */
910    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
911
912    /**
913     * All of the processes that have been forced to be important.  The key
914     * is the pid of the caller who requested it (we hold a death
915     * link on it).
916     */
917    abstract class ImportanceToken implements IBinder.DeathRecipient {
918        final int pid;
919        final IBinder token;
920        final String reason;
921
922        ImportanceToken(int _pid, IBinder _token, String _reason) {
923            pid = _pid;
924            token = _token;
925            reason = _reason;
926        }
927
928        @Override
929        public String toString() {
930            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
931                    + " " + reason + " " + pid + " " + token + " }";
932        }
933    }
934    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
935
936    /**
937     * List of records for processes that someone had tried to start before the
938     * system was ready.  We don't start them at that point, but ensure they
939     * are started by the time booting is complete.
940     */
941    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
942
943    /**
944     * List of persistent applications that are in the process
945     * of being started.
946     */
947    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
948
949    /**
950     * Processes that are being forcibly torn down.
951     */
952    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
953
954    /**
955     * List of running applications, sorted by recent usage.
956     * The first entry in the list is the least recently used.
957     */
958    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
959
960    /**
961     * Where in mLruProcesses that the processes hosting activities start.
962     */
963    int mLruProcessActivityStart = 0;
964
965    /**
966     * Where in mLruProcesses that the processes hosting services start.
967     * This is after (lower index) than mLruProcessesActivityStart.
968     */
969    int mLruProcessServiceStart = 0;
970
971    /**
972     * List of processes that should gc as soon as things are idle.
973     */
974    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
975
976    /**
977     * Processes we want to collect PSS data from.
978     */
979    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
980
981    private boolean mBinderTransactionTrackingEnabled = false;
982
983    /**
984     * Last time we requested PSS data of all processes.
985     */
986    long mLastFullPssTime = SystemClock.uptimeMillis();
987
988    /**
989     * If set, the next time we collect PSS data we should do a full collection
990     * with data from native processes and the kernel.
991     */
992    boolean mFullPssPending = false;
993
994    /**
995     * This is the process holding what we currently consider to be
996     * the "home" activity.
997     */
998    ProcessRecord mHomeProcess;
999
1000    /**
1001     * This is the process holding the activity the user last visited that
1002     * is in a different process from the one they are currently in.
1003     */
1004    ProcessRecord mPreviousProcess;
1005
1006    /**
1007     * The time at which the previous process was last visible.
1008     */
1009    long mPreviousProcessVisibleTime;
1010
1011    /**
1012     * Track all uids that have actively running processes.
1013     */
1014    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
1015
1016    /**
1017     * This is for verifying the UID report flow.
1018     */
1019    static final boolean VALIDATE_UID_STATES = true;
1020    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
1021
1022    /**
1023     * Packages that the user has asked to have run in screen size
1024     * compatibility mode instead of filling the screen.
1025     */
1026    final CompatModePackages mCompatModePackages;
1027
1028    /**
1029     * Set of IntentSenderRecord objects that are currently active.
1030     */
1031    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1032            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1033
1034    /**
1035     * Fingerprints (hashCode()) of stack traces that we've
1036     * already logged DropBox entries for.  Guarded by itself.  If
1037     * something (rogue user app) forces this over
1038     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1039     */
1040    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1041    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1042
1043    /**
1044     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1045     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1046     */
1047    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1048
1049    /**
1050     * Resolver for broadcast intents to registered receivers.
1051     * Holds BroadcastFilter (subclass of IntentFilter).
1052     */
1053    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1054            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1055        @Override
1056        protected boolean allowFilterResult(
1057                BroadcastFilter filter, List<BroadcastFilter> dest) {
1058            IBinder target = filter.receiverList.receiver.asBinder();
1059            for (int i = dest.size() - 1; i >= 0; i--) {
1060                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1061                    return false;
1062                }
1063            }
1064            return true;
1065        }
1066
1067        @Override
1068        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1069            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1070                    || userId == filter.owningUserId) {
1071                return super.newResult(filter, match, userId);
1072            }
1073            return null;
1074        }
1075
1076        @Override
1077        protected BroadcastFilter[] newArray(int size) {
1078            return new BroadcastFilter[size];
1079        }
1080
1081        @Override
1082        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1083            return packageName.equals(filter.packageName);
1084        }
1085    };
1086
1087    /**
1088     * State of all active sticky broadcasts per user.  Keys are the action of the
1089     * sticky Intent, values are an ArrayList of all broadcasted intents with
1090     * that action (which should usually be one).  The SparseArray is keyed
1091     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1092     * for stickies that are sent to all users.
1093     */
1094    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1095            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1096
1097    final ActiveServices mServices;
1098
1099    final static class Association {
1100        final int mSourceUid;
1101        final String mSourceProcess;
1102        final int mTargetUid;
1103        final ComponentName mTargetComponent;
1104        final String mTargetProcess;
1105
1106        int mCount;
1107        long mTime;
1108
1109        int mNesting;
1110        long mStartTime;
1111
1112        // states of the source process when the bind occurred.
1113        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1114        long mLastStateUptime;
1115        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1116                - ActivityManager.MIN_PROCESS_STATE+1];
1117
1118        Association(int sourceUid, String sourceProcess, int targetUid,
1119                ComponentName targetComponent, String targetProcess) {
1120            mSourceUid = sourceUid;
1121            mSourceProcess = sourceProcess;
1122            mTargetUid = targetUid;
1123            mTargetComponent = targetComponent;
1124            mTargetProcess = targetProcess;
1125        }
1126    }
1127
1128    /**
1129     * When service association tracking is enabled, this is all of the associations we
1130     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1131     * -> association data.
1132     */
1133    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1134            mAssociations = new SparseArray<>();
1135    boolean mTrackingAssociations;
1136
1137    /**
1138     * Backup/restore process management
1139     */
1140    String mBackupAppName = null;
1141    BackupRecord mBackupTarget = null;
1142
1143    final ProviderMap mProviderMap;
1144
1145    /**
1146     * List of content providers who have clients waiting for them.  The
1147     * application is currently being launched and the provider will be
1148     * removed from this list once it is published.
1149     */
1150    final ArrayList<ContentProviderRecord> mLaunchingProviders
1151            = new ArrayList<ContentProviderRecord>();
1152
1153    /**
1154     * File storing persisted {@link #mGrantedUriPermissions}.
1155     */
1156    private final AtomicFile mGrantFile;
1157
1158    /** XML constants used in {@link #mGrantFile} */
1159    private static final String TAG_URI_GRANTS = "uri-grants";
1160    private static final String TAG_URI_GRANT = "uri-grant";
1161    private static final String ATTR_USER_HANDLE = "userHandle";
1162    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1163    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1164    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1165    private static final String ATTR_TARGET_PKG = "targetPkg";
1166    private static final String ATTR_URI = "uri";
1167    private static final String ATTR_MODE_FLAGS = "modeFlags";
1168    private static final String ATTR_CREATED_TIME = "createdTime";
1169    private static final String ATTR_PREFIX = "prefix";
1170
1171    /**
1172     * Global set of specific {@link Uri} permissions that have been granted.
1173     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1174     * to {@link UriPermission#uri} to {@link UriPermission}.
1175     */
1176    @GuardedBy("this")
1177    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1178            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1179
1180    public static class GrantUri {
1181        public final int sourceUserId;
1182        public final Uri uri;
1183        public boolean prefix;
1184
1185        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1186            this.sourceUserId = sourceUserId;
1187            this.uri = uri;
1188            this.prefix = prefix;
1189        }
1190
1191        @Override
1192        public int hashCode() {
1193            int hashCode = 1;
1194            hashCode = 31 * hashCode + sourceUserId;
1195            hashCode = 31 * hashCode + uri.hashCode();
1196            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1197            return hashCode;
1198        }
1199
1200        @Override
1201        public boolean equals(Object o) {
1202            if (o instanceof GrantUri) {
1203                GrantUri other = (GrantUri) o;
1204                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1205                        && prefix == other.prefix;
1206            }
1207            return false;
1208        }
1209
1210        @Override
1211        public String toString() {
1212            String result = uri.toString() + " [user " + sourceUserId + "]";
1213            if (prefix) result += " [prefix]";
1214            return result;
1215        }
1216
1217        public String toSafeString() {
1218            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1219            if (prefix) result += " [prefix]";
1220            return result;
1221        }
1222
1223        public void writeToProto(ProtoOutputStream proto, long fieldId) {
1224            long token = proto.start(fieldId);
1225            proto.write(GrantUriProto.URI, uri.toString());
1226            proto.write(GrantUriProto.SOURCE_USER_ID, sourceUserId);
1227            proto.end(token);
1228        }
1229
1230        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1231            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1232                    ContentProvider.getUriWithoutUserId(uri), false);
1233        }
1234    }
1235
1236    CoreSettingsObserver mCoreSettingsObserver;
1237
1238    FontScaleSettingObserver mFontScaleSettingObserver;
1239
1240    private final class FontScaleSettingObserver extends ContentObserver {
1241        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1242
1243        public FontScaleSettingObserver() {
1244            super(mHandler);
1245            ContentResolver resolver = mContext.getContentResolver();
1246            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1247        }
1248
1249        @Override
1250        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1251            if (mFontScaleUri.equals(uri)) {
1252                updateFontScaleIfNeeded(userId);
1253            }
1254        }
1255    }
1256
1257    /**
1258     * Thread-local storage used to carry caller permissions over through
1259     * indirect content-provider access.
1260     */
1261    private class Identity {
1262        public final IBinder token;
1263        public final int pid;
1264        public final int uid;
1265
1266        Identity(IBinder _token, int _pid, int _uid) {
1267            token = _token;
1268            pid = _pid;
1269            uid = _uid;
1270        }
1271    }
1272
1273    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1274
1275    /**
1276     * All information we have collected about the runtime performance of
1277     * any user id that can impact battery performance.
1278     */
1279    final BatteryStatsService mBatteryStatsService;
1280
1281    /**
1282     * Information about component usage
1283     */
1284    UsageStatsManagerInternal mUsageStatsService;
1285
1286    /**
1287     * Access to DeviceIdleController service.
1288     */
1289    DeviceIdleController.LocalService mLocalDeviceIdleController;
1290
1291    /**
1292     * Set of app ids that are whitelisted for device idle and thus background check.
1293     */
1294    int[] mDeviceIdleWhitelist = new int[0];
1295
1296    /**
1297     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1298     */
1299    int[] mDeviceIdleTempWhitelist = new int[0];
1300
1301    static final class PendingTempWhitelist {
1302        final int targetUid;
1303        final long duration;
1304        final String tag;
1305
1306        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1307            targetUid = _targetUid;
1308            duration = _duration;
1309            tag = _tag;
1310        }
1311    }
1312
1313    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1314
1315    /**
1316     * Information about and control over application operations
1317     */
1318    final AppOpsService mAppOpsService;
1319
1320    /** Current sequencing integer of the configuration, for skipping old configurations. */
1321    private int mConfigurationSeq;
1322
1323    /**
1324     * Temp object used when global and/or display override configuration is updated. It is also
1325     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1326     * anyone...
1327     */
1328    private Configuration mTempConfig = new Configuration();
1329
1330    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1331            new UpdateConfigurationResult();
1332    private static final class UpdateConfigurationResult {
1333        // Configuration changes that were updated.
1334        int changes;
1335        // If the activity was relaunched to match the new configuration.
1336        boolean activityRelaunched;
1337
1338        void reset() {
1339            changes = 0;
1340            activityRelaunched = false;
1341        }
1342    }
1343
1344    boolean mSuppressResizeConfigChanges;
1345
1346    /**
1347     * Hardware-reported OpenGLES version.
1348     */
1349    final int GL_ES_VERSION;
1350
1351    /**
1352     * List of initialization arguments to pass to all processes when binding applications to them.
1353     * For example, references to the commonly used services.
1354     */
1355    HashMap<String, IBinder> mAppBindArgs;
1356    HashMap<String, IBinder> mIsolatedAppBindArgs;
1357
1358    /**
1359     * Temporary to avoid allocations.  Protected by main lock.
1360     */
1361    final StringBuilder mStringBuilder = new StringBuilder(256);
1362
1363    /**
1364     * Used to control how we initialize the service.
1365     */
1366    ComponentName mTopComponent;
1367    String mTopAction = Intent.ACTION_MAIN;
1368    String mTopData;
1369
1370    volatile boolean mProcessesReady = false;
1371    volatile boolean mSystemReady = false;
1372    volatile boolean mOnBattery = false;
1373    volatile int mFactoryTest;
1374
1375    @GuardedBy("this") boolean mBooting = false;
1376    @GuardedBy("this") boolean mCallFinishBooting = false;
1377    @GuardedBy("this") boolean mBootAnimationComplete = false;
1378    @GuardedBy("this") boolean mLaunchWarningShown = false;
1379    private @GuardedBy("this") boolean mCheckedForSetup = false;
1380
1381    final Context mContext;
1382
1383    /**
1384     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1385     * change at runtime. Use mContext for non-UI purposes.
1386     */
1387    final Context mUiContext;
1388
1389    /**
1390     * The time at which we will allow normal application switches again,
1391     * after a call to {@link #stopAppSwitches()}.
1392     */
1393    long mAppSwitchesAllowedTime;
1394
1395    /**
1396     * This is set to true after the first switch after mAppSwitchesAllowedTime
1397     * is set; any switches after that will clear the time.
1398     */
1399    boolean mDidAppSwitch;
1400
1401    /**
1402     * Last time (in uptime) at which we checked for power usage.
1403     */
1404    long mLastPowerCheckUptime;
1405
1406    /**
1407     * Set while we are wanting to sleep, to prevent any
1408     * activities from being started/resumed.
1409     *
1410     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1411     *
1412     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1413     * while in the sleep state until there is a pending transition out of sleep, in which case
1414     * mSleeping is set to false, and remains false while awake.
1415     *
1416     * Whether mSleeping can quickly toggled between true/false without the device actually
1417     * display changing states is undefined.
1418     */
1419    private boolean mSleeping = false;
1420
1421    /**
1422     * The process state used for processes that are running the top activities.
1423     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1424     */
1425    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1426
1427    /**
1428     * Set while we are running a voice interaction.  This overrides
1429     * sleeping while it is active.
1430     */
1431    IVoiceInteractionSession mRunningVoice;
1432
1433    /**
1434     * For some direct access we need to power manager.
1435     */
1436    PowerManagerInternal mLocalPowerManager;
1437
1438    /**
1439     * We want to hold a wake lock while running a voice interaction session, since
1440     * this may happen with the screen off and we need to keep the CPU running to
1441     * be able to continue to interact with the user.
1442     */
1443    PowerManager.WakeLock mVoiceWakeLock;
1444
1445    /**
1446     * State of external calls telling us if the device is awake or asleep.
1447     */
1448    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1449
1450    /**
1451     * Set if we are shutting down the system, similar to sleeping.
1452     */
1453    boolean mShuttingDown = false;
1454
1455    /**
1456     * Current sequence id for oom_adj computation traversal.
1457     */
1458    int mAdjSeq = 0;
1459
1460    /**
1461     * Current sequence id for process LRU updating.
1462     */
1463    int mLruSeq = 0;
1464
1465    /**
1466     * Keep track of the non-cached/empty process we last found, to help
1467     * determine how to distribute cached/empty processes next time.
1468     */
1469    int mNumNonCachedProcs = 0;
1470
1471    /**
1472     * Keep track of the number of cached hidden procs, to balance oom adj
1473     * distribution between those and empty procs.
1474     */
1475    int mNumCachedHiddenProcs = 0;
1476
1477    /**
1478     * Keep track of the number of service processes we last found, to
1479     * determine on the next iteration which should be B services.
1480     */
1481    int mNumServiceProcs = 0;
1482    int mNewNumAServiceProcs = 0;
1483    int mNewNumServiceProcs = 0;
1484
1485    /**
1486     * Allow the current computed overall memory level of the system to go down?
1487     * This is set to false when we are killing processes for reasons other than
1488     * memory management, so that the now smaller process list will not be taken as
1489     * an indication that memory is tighter.
1490     */
1491    boolean mAllowLowerMemLevel = false;
1492
1493    /**
1494     * The last computed memory level, for holding when we are in a state that
1495     * processes are going away for other reasons.
1496     */
1497    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1498
1499    /**
1500     * The last total number of process we have, to determine if changes actually look
1501     * like a shrinking number of process due to lower RAM.
1502     */
1503    int mLastNumProcesses;
1504
1505    /**
1506     * The uptime of the last time we performed idle maintenance.
1507     */
1508    long mLastIdleTime = SystemClock.uptimeMillis();
1509
1510    /**
1511     * Total time spent with RAM that has been added in the past since the last idle time.
1512     */
1513    long mLowRamTimeSinceLastIdle = 0;
1514
1515    /**
1516     * If RAM is currently low, when that horrible situation started.
1517     */
1518    long mLowRamStartTime = 0;
1519
1520    /**
1521     * For reporting to battery stats the current top application.
1522     */
1523    private String mCurResumedPackage = null;
1524    private int mCurResumedUid = -1;
1525
1526    /**
1527     * For reporting to battery stats the apps currently running foreground
1528     * service.  The ProcessMap is package/uid tuples; each of these contain
1529     * an array of the currently foreground processes.
1530     */
1531    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1532            = new ProcessMap<ArrayList<ProcessRecord>>();
1533
1534    /**
1535     * Set if the systemServer made a call to enterSafeMode.
1536     */
1537    boolean mSafeMode;
1538
1539    /**
1540     * If true, we are running under a test environment so will sample PSS from processes
1541     * much more rapidly to try to collect better data when the tests are rapidly
1542     * running through apps.
1543     */
1544    boolean mTestPssMode = false;
1545
1546    String mDebugApp = null;
1547    boolean mWaitForDebugger = false;
1548    boolean mDebugTransient = false;
1549    String mOrigDebugApp = null;
1550    boolean mOrigWaitForDebugger = false;
1551    boolean mAlwaysFinishActivities = false;
1552    boolean mForceResizableActivities;
1553    /**
1554     * Flag that indicates if multi-window is enabled.
1555     *
1556     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1557     * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1558     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1559     * At least one of the forms of multi-window must be enabled in order for this flag to be
1560     * initialized to 'true'.
1561     *
1562     * @see #mSupportsSplitScreenMultiWindow
1563     * @see #mSupportsFreeformWindowManagement
1564     * @see #mSupportsPictureInPicture
1565     * @see #mSupportsMultiDisplay
1566     */
1567    boolean mSupportsMultiWindow;
1568    boolean mSupportsSplitScreenMultiWindow;
1569    boolean mSupportsFreeformWindowManagement;
1570    boolean mSupportsPictureInPicture;
1571    boolean mSupportsMultiDisplay;
1572    boolean mSupportsLeanbackOnly;
1573    IActivityController mController = null;
1574    boolean mControllerIsAMonkey = false;
1575    String mProfileApp = null;
1576    ProcessRecord mProfileProc = null;
1577    ProfilerInfo mProfilerInfo = null;
1578    int mProfileType = 0;
1579    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1580    String mMemWatchDumpProcName;
1581    String mMemWatchDumpFile;
1582    int mMemWatchDumpPid;
1583    int mMemWatchDumpUid;
1584    String mTrackAllocationApp = null;
1585    String mNativeDebuggingApp = null;
1586
1587    final long[] mTmpLong = new long[2];
1588
1589    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1590
1591    /**
1592     * A global counter for generating sequence numbers.
1593     * This value will be used when incrementing sequence numbers in individual uidRecords.
1594     *
1595     * Having a global counter ensures that seq numbers are monotonically increasing for a
1596     * particular uid even when the uidRecord is re-created.
1597     */
1598    @GuardedBy("this")
1599    @VisibleForTesting
1600    long mProcStateSeqCounter = 0;
1601
1602    /**
1603     * A global counter for generating sequence numbers to uniquely identify pending process starts.
1604     */
1605    @GuardedBy("this")
1606    private long mProcStartSeqCounter = 0;
1607
1608    /**
1609     * Contains {@link ProcessRecord} objects for pending process starts.
1610     *
1611     * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
1612     */
1613    @GuardedBy("this")
1614    private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
1615
1616    private final Injector mInjector;
1617
1618    static final class ProcessChangeItem {
1619        static final int CHANGE_ACTIVITIES = 1<<0;
1620        int changes;
1621        int uid;
1622        int pid;
1623        int processState;
1624        boolean foregroundActivities;
1625    }
1626
1627    static final class UidObserverRegistration {
1628        final int uid;
1629        final String pkg;
1630        final int which;
1631        final int cutpoint;
1632
1633        final SparseIntArray lastProcStates;
1634
1635        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1636            uid = _uid;
1637            pkg = _pkg;
1638            which = _which;
1639            cutpoint = _cutpoint;
1640            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1641                lastProcStates = new SparseIntArray();
1642            } else {
1643                lastProcStates = null;
1644            }
1645        }
1646    }
1647
1648    final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1649
1650    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1651    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1652
1653    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1654    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1655
1656    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1657    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1658
1659    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1660    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1661
1662    OomAdjObserver mCurOomAdjObserver;
1663    int mCurOomAdjUid;
1664
1665    interface OomAdjObserver {
1666        void onOomAdjMessage(String msg);
1667    }
1668
1669    /**
1670     * Runtime CPU use collection thread.  This object's lock is used to
1671     * perform synchronization with the thread (notifying it to run).
1672     */
1673    final Thread mProcessCpuThread;
1674
1675    /**
1676     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1677     * Must acquire this object's lock when accessing it.
1678     * NOTE: this lock will be held while doing long operations (trawling
1679     * through all processes in /proc), so it should never be acquired by
1680     * any critical paths such as when holding the main activity manager lock.
1681     */
1682    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1683            MONITOR_THREAD_CPU_USAGE);
1684    final AtomicLong mLastCpuTime = new AtomicLong(0);
1685    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1686    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1687
1688    long mLastWriteTime = 0;
1689
1690    /**
1691     * Used to retain an update lock when the foreground activity is in
1692     * immersive mode.
1693     */
1694    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1695
1696    /**
1697     * Set to true after the system has finished booting.
1698     */
1699    boolean mBooted = false;
1700
1701    WindowManagerService mWindowManager;
1702    final ActivityThread mSystemThread;
1703
1704    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1705        final ProcessRecord mApp;
1706        final int mPid;
1707        final IApplicationThread mAppThread;
1708
1709        AppDeathRecipient(ProcessRecord app, int pid,
1710                IApplicationThread thread) {
1711            if (DEBUG_ALL) Slog.v(
1712                TAG, "New death recipient " + this
1713                + " for thread " + thread.asBinder());
1714            mApp = app;
1715            mPid = pid;
1716            mAppThread = thread;
1717        }
1718
1719        @Override
1720        public void binderDied() {
1721            if (DEBUG_ALL) Slog.v(
1722                TAG, "Death received in " + this
1723                + " for thread " + mAppThread.asBinder());
1724            synchronized(ActivityManagerService.this) {
1725                appDiedLocked(mApp, mPid, mAppThread, true);
1726            }
1727        }
1728    }
1729
1730    static final int SHOW_ERROR_UI_MSG = 1;
1731    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1732    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1733    static final int UPDATE_CONFIGURATION_MSG = 4;
1734    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1735    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1736    static final int SERVICE_TIMEOUT_MSG = 12;
1737    static final int UPDATE_TIME_ZONE = 13;
1738    static final int SHOW_UID_ERROR_UI_MSG = 14;
1739    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1740    static final int PROC_START_TIMEOUT_MSG = 20;
1741    static final int KILL_APPLICATION_MSG = 22;
1742    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1743    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1744    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1745    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1746    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1747    static final int CLEAR_DNS_CACHE_MSG = 28;
1748    static final int UPDATE_HTTP_PROXY_MSG = 29;
1749    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1750    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1751    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1752    static final int REPORT_MEM_USAGE_MSG = 33;
1753    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1754    static final int PERSIST_URI_GRANTS_MSG = 38;
1755    static final int REQUEST_ALL_PSS_MSG = 39;
1756    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1757    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1758    static final int FINISH_BOOTING_MSG = 45;
1759    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1760    static final int DISMISS_DIALOG_UI_MSG = 48;
1761    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1762    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1763    static final int DELETE_DUMPHEAP_MSG = 51;
1764    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1765    static final int REPORT_TIME_TRACKER_MSG = 54;
1766    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1767    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1768    static final int IDLE_UIDS_MSG = 58;
1769    static final int LOG_STACK_STATE = 60;
1770    static final int VR_MODE_CHANGE_MSG = 61;
1771    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1772    static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
1773    static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
1774    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1775    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1776    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1777    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1778    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1779
1780    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1781    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1782    static final int FIRST_COMPAT_MODE_MSG = 300;
1783    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1784
1785    static ServiceThread sKillThread = null;
1786    static KillHandler sKillHandler = null;
1787
1788    CompatModeDialog mCompatModeDialog;
1789    long mLastMemUsageReportTime = 0;
1790
1791    /**
1792     * Flag whether the current user is a "monkey", i.e. whether
1793     * the UI is driven by a UI automation tool.
1794     */
1795    private boolean mUserIsMonkey;
1796
1797    /** The dimensions of the thumbnails in the Recents UI. */
1798    int mThumbnailWidth;
1799    int mThumbnailHeight;
1800    float mFullscreenThumbnailScale;
1801
1802    final ServiceThread mHandlerThread;
1803    final MainHandler mHandler;
1804    final Handler mUiHandler;
1805    final ServiceThread mProcStartHandlerThread;
1806    final Handler mProcStartHandler;
1807
1808    final ActivityManagerConstants mConstants;
1809
1810    PackageManagerInternal mPackageManagerInt;
1811
1812    // VoiceInteraction session ID that changes for each new request except when
1813    // being called for multiwindow assist in a single session.
1814    private int mViSessionId = 1000;
1815
1816    final boolean mPermissionReviewRequired;
1817
1818    /**
1819     * Whether to force background check on all apps (for battery saver) or not.
1820     */
1821    boolean mForceBackgroundCheck;
1822
1823    private static String sTheRealBuildSerial = Build.UNKNOWN;
1824
1825    /**
1826     * Current global configuration information. Contains general settings for the entire system,
1827     * also corresponds to the merged configuration of the default display.
1828     */
1829    Configuration getGlobalConfiguration() {
1830        return mStackSupervisor.getConfiguration();
1831    }
1832
1833    final class KillHandler extends Handler {
1834        static final int KILL_PROCESS_GROUP_MSG = 4000;
1835
1836        public KillHandler(Looper looper) {
1837            super(looper, null, true);
1838        }
1839
1840        @Override
1841        public void handleMessage(Message msg) {
1842            switch (msg.what) {
1843                case KILL_PROCESS_GROUP_MSG:
1844                {
1845                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1846                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1847                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1848                }
1849                break;
1850
1851                default:
1852                    super.handleMessage(msg);
1853            }
1854        }
1855    }
1856
1857    final class UiHandler extends Handler {
1858        public UiHandler() {
1859            super(com.android.server.UiThread.get().getLooper(), null, true);
1860        }
1861
1862        @Override
1863        public void handleMessage(Message msg) {
1864            switch (msg.what) {
1865            case SHOW_ERROR_UI_MSG: {
1866                mAppErrors.handleShowAppErrorUi(msg);
1867                ensureBootCompleted();
1868            } break;
1869            case SHOW_NOT_RESPONDING_UI_MSG: {
1870                mAppErrors.handleShowAnrUi(msg);
1871                ensureBootCompleted();
1872            } break;
1873            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1874                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1875                synchronized (ActivityManagerService.this) {
1876                    ProcessRecord proc = (ProcessRecord) data.get("app");
1877                    if (proc == null) {
1878                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1879                        break;
1880                    }
1881                    if (proc.crashDialog != null) {
1882                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1883                        return;
1884                    }
1885                    AppErrorResult res = (AppErrorResult) data.get("result");
1886                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1887                        Dialog d = new StrictModeViolationDialog(mUiContext,
1888                                ActivityManagerService.this, res, proc);
1889                        d.show();
1890                        proc.crashDialog = d;
1891                    } else {
1892                        // The device is asleep, so just pretend that the user
1893                        // saw a crash dialog and hit "force quit".
1894                        res.set(0);
1895                    }
1896                }
1897                ensureBootCompleted();
1898            } break;
1899            case SHOW_FACTORY_ERROR_UI_MSG: {
1900                Dialog d = new FactoryErrorDialog(
1901                        mUiContext, msg.getData().getCharSequence("msg"));
1902                d.show();
1903                ensureBootCompleted();
1904            } break;
1905            case WAIT_FOR_DEBUGGER_UI_MSG: {
1906                synchronized (ActivityManagerService.this) {
1907                    ProcessRecord app = (ProcessRecord)msg.obj;
1908                    if (msg.arg1 != 0) {
1909                        if (!app.waitedForDebugger) {
1910                            Dialog d = new AppWaitingForDebuggerDialog(
1911                                    ActivityManagerService.this,
1912                                    mUiContext, app);
1913                            app.waitDialog = d;
1914                            app.waitedForDebugger = true;
1915                            d.show();
1916                        }
1917                    } else {
1918                        if (app.waitDialog != null) {
1919                            app.waitDialog.dismiss();
1920                            app.waitDialog = null;
1921                        }
1922                    }
1923                }
1924            } break;
1925            case SHOW_UID_ERROR_UI_MSG: {
1926                if (mShowDialogs) {
1927                    AlertDialog d = new BaseErrorDialog(mUiContext);
1928                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1929                    d.setCancelable(false);
1930                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1931                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1932                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1933                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1934                    d.show();
1935                }
1936            } break;
1937            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1938                if (mShowDialogs) {
1939                    AlertDialog d = new BaseErrorDialog(mUiContext);
1940                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1941                    d.setCancelable(false);
1942                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1943                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1944                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1945                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1946                    d.show();
1947                }
1948            } break;
1949            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1950                synchronized (ActivityManagerService.this) {
1951                    ActivityRecord ar = (ActivityRecord) msg.obj;
1952                    if (mCompatModeDialog != null) {
1953                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1954                                ar.info.applicationInfo.packageName)) {
1955                            return;
1956                        }
1957                        mCompatModeDialog.dismiss();
1958                        mCompatModeDialog = null;
1959                    }
1960                    if (ar != null && false) {
1961                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1962                                ar.packageName)) {
1963                            int mode = mCompatModePackages.computeCompatModeLocked(
1964                                    ar.info.applicationInfo);
1965                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1966                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1967                                mCompatModeDialog = new CompatModeDialog(
1968                                        ActivityManagerService.this, mUiContext,
1969                                        ar.info.applicationInfo);
1970                                mCompatModeDialog.show();
1971                            }
1972                        }
1973                    }
1974                }
1975                break;
1976            }
1977            case DISMISS_DIALOG_UI_MSG: {
1978                final Dialog d = (Dialog) msg.obj;
1979                d.dismiss();
1980                break;
1981            }
1982            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1983                dispatchProcessesChanged();
1984                break;
1985            }
1986            case DISPATCH_PROCESS_DIED_UI_MSG: {
1987                final int pid = msg.arg1;
1988                final int uid = msg.arg2;
1989                dispatchProcessDied(pid, uid);
1990                break;
1991            }
1992            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1993                dispatchUidsChanged();
1994            } break;
1995            case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1996                dispatchOomAdjObserver((String)msg.obj);
1997            } break;
1998            case PUSH_TEMP_WHITELIST_UI_MSG: {
1999                pushTempWhitelist();
2000            } break;
2001            }
2002        }
2003    }
2004
2005    final class MainHandler extends Handler {
2006        public MainHandler(Looper looper) {
2007            super(looper, null, true);
2008        }
2009
2010        @Override
2011        public void handleMessage(Message msg) {
2012            switch (msg.what) {
2013            case UPDATE_CONFIGURATION_MSG: {
2014                final ContentResolver resolver = mContext.getContentResolver();
2015                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
2016                        msg.arg1);
2017            } break;
2018            case GC_BACKGROUND_PROCESSES_MSG: {
2019                synchronized (ActivityManagerService.this) {
2020                    performAppGcsIfAppropriateLocked();
2021                }
2022            } break;
2023            case SERVICE_TIMEOUT_MSG: {
2024                mServices.serviceTimeout((ProcessRecord)msg.obj);
2025            } break;
2026            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
2027                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
2028            } break;
2029            case SERVICE_FOREGROUND_CRASH_MSG: {
2030                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
2031            } break;
2032            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
2033                RemoteCallbackList<IResultReceiver> callbacks
2034                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
2035                int N = callbacks.beginBroadcast();
2036                for (int i = 0; i < N; i++) {
2037                    try {
2038                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
2039                    } catch (RemoteException e) {
2040                    }
2041                }
2042                callbacks.finishBroadcast();
2043            } break;
2044            case UPDATE_TIME_ZONE: {
2045                synchronized (ActivityManagerService.this) {
2046                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2047                        ProcessRecord r = mLruProcesses.get(i);
2048                        if (r.thread != null) {
2049                            try {
2050                                r.thread.updateTimeZone();
2051                            } catch (RemoteException ex) {
2052                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2053                            }
2054                        }
2055                    }
2056                }
2057            } break;
2058            case CLEAR_DNS_CACHE_MSG: {
2059                synchronized (ActivityManagerService.this) {
2060                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2061                        ProcessRecord r = mLruProcesses.get(i);
2062                        if (r.thread != null) {
2063                            try {
2064                                r.thread.clearDnsCache();
2065                            } catch (RemoteException ex) {
2066                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2067                            }
2068                        }
2069                    }
2070                }
2071            } break;
2072            case UPDATE_HTTP_PROXY_MSG: {
2073                ProxyInfo proxy = (ProxyInfo)msg.obj;
2074                String host = "";
2075                String port = "";
2076                String exclList = "";
2077                Uri pacFileUrl = Uri.EMPTY;
2078                if (proxy != null) {
2079                    host = proxy.getHost();
2080                    port = Integer.toString(proxy.getPort());
2081                    exclList = proxy.getExclusionListAsString();
2082                    pacFileUrl = proxy.getPacFileUrl();
2083                }
2084                synchronized (ActivityManagerService.this) {
2085                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2086                        ProcessRecord r = mLruProcesses.get(i);
2087                        // Don't dispatch to isolated processes as they can't access
2088                        // ConnectivityManager and don't have network privileges anyway.
2089                        if (r.thread != null && !r.isolated) {
2090                            try {
2091                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2092                            } catch (RemoteException ex) {
2093                                Slog.w(TAG, "Failed to update http proxy for: " +
2094                                        r.info.processName);
2095                            }
2096                        }
2097                    }
2098                }
2099            } break;
2100            case PROC_START_TIMEOUT_MSG: {
2101                ProcessRecord app = (ProcessRecord)msg.obj;
2102                synchronized (ActivityManagerService.this) {
2103                    processStartTimedOutLocked(app);
2104                }
2105            } break;
2106            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2107                ProcessRecord app = (ProcessRecord)msg.obj;
2108                synchronized (ActivityManagerService.this) {
2109                    processContentProviderPublishTimedOutLocked(app);
2110                }
2111            } break;
2112            case KILL_APPLICATION_MSG: {
2113                synchronized (ActivityManagerService.this) {
2114                    final int appId = msg.arg1;
2115                    final int userId = msg.arg2;
2116                    Bundle bundle = (Bundle)msg.obj;
2117                    String pkg = bundle.getString("pkg");
2118                    String reason = bundle.getString("reason");
2119                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2120                            false, userId, reason);
2121                }
2122            } break;
2123            case FINALIZE_PENDING_INTENT_MSG: {
2124                ((PendingIntentRecord)msg.obj).completeFinalize();
2125            } break;
2126            case POST_HEAVY_NOTIFICATION_MSG: {
2127                INotificationManager inm = NotificationManager.getService();
2128                if (inm == null) {
2129                    return;
2130                }
2131
2132                ActivityRecord root = (ActivityRecord)msg.obj;
2133                ProcessRecord process = root.app;
2134                if (process == null) {
2135                    return;
2136                }
2137
2138                try {
2139                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2140                    String text = mContext.getString(R.string.heavy_weight_notification,
2141                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2142                    Notification notification =
2143                            new Notification.Builder(context,
2144                                    SystemNotificationChannels.HEAVY_WEIGHT_APP)
2145                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2146                            .setWhen(0)
2147                            .setOngoing(true)
2148                            .setTicker(text)
2149                            .setColor(mContext.getColor(
2150                                    com.android.internal.R.color.system_notification_accent_color))
2151                            .setContentTitle(text)
2152                            .setContentText(
2153                                    mContext.getText(R.string.heavy_weight_notification_detail))
2154                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2155                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2156                                    new UserHandle(root.userId)))
2157                            .build();
2158                    try {
2159                        inm.enqueueNotificationWithTag("android", "android", null,
2160                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2161                                notification, root.userId);
2162                    } catch (RuntimeException e) {
2163                        Slog.w(ActivityManagerService.TAG,
2164                                "Error showing notification for heavy-weight app", e);
2165                    } catch (RemoteException e) {
2166                    }
2167                } catch (NameNotFoundException e) {
2168                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2169                }
2170            } break;
2171            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2172                INotificationManager inm = NotificationManager.getService();
2173                if (inm == null) {
2174                    return;
2175                }
2176                try {
2177                    inm.cancelNotificationWithTag("android", null,
2178                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2179                } catch (RuntimeException e) {
2180                    Slog.w(ActivityManagerService.TAG,
2181                            "Error canceling notification for service", e);
2182                } catch (RemoteException e) {
2183                }
2184            } break;
2185            case CHECK_EXCESSIVE_POWER_USE_MSG: {
2186                synchronized (ActivityManagerService.this) {
2187                    checkExcessivePowerUsageLocked();
2188                    removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2189                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2190                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2191                }
2192            } break;
2193            case REPORT_MEM_USAGE_MSG: {
2194                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2195                Thread thread = new Thread() {
2196                    @Override public void run() {
2197                        reportMemUsage(memInfos);
2198                    }
2199                };
2200                thread.start();
2201                break;
2202            }
2203            case IMMERSIVE_MODE_LOCK_MSG: {
2204                final boolean nextState = (msg.arg1 != 0);
2205                if (mUpdateLock.isHeld() != nextState) {
2206                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2207                            "Applying new update lock state '" + nextState
2208                            + "' for " + (ActivityRecord)msg.obj);
2209                    if (nextState) {
2210                        mUpdateLock.acquire();
2211                    } else {
2212                        mUpdateLock.release();
2213                    }
2214                }
2215                break;
2216            }
2217            case PERSIST_URI_GRANTS_MSG: {
2218                writeGrantedUriPermissions();
2219                break;
2220            }
2221            case REQUEST_ALL_PSS_MSG: {
2222                synchronized (ActivityManagerService.this) {
2223                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2224                }
2225                break;
2226            }
2227            case UPDATE_TIME_PREFERENCE_MSG: {
2228                // The user's time format preference might have changed.
2229                // For convenience we re-use the Intent extra values.
2230                synchronized (ActivityManagerService.this) {
2231                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2232                        ProcessRecord r = mLruProcesses.get(i);
2233                        if (r.thread != null) {
2234                            try {
2235                                r.thread.updateTimePrefs(msg.arg1);
2236                            } catch (RemoteException ex) {
2237                                Slog.w(TAG, "Failed to update preferences for: "
2238                                        + r.info.processName);
2239                            }
2240                        }
2241                    }
2242                }
2243                break;
2244            }
2245            case ENTER_ANIMATION_COMPLETE_MSG: {
2246                synchronized (ActivityManagerService.this) {
2247                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2248                    if (r != null && r.app != null && r.app.thread != null) {
2249                        try {
2250                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2251                        } catch (RemoteException e) {
2252                        }
2253                    }
2254                }
2255                break;
2256            }
2257            case FINISH_BOOTING_MSG: {
2258                if (msg.arg1 != 0) {
2259                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2260                    finishBooting();
2261                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2262                }
2263                if (msg.arg2 != 0) {
2264                    enableScreenAfterBoot();
2265                }
2266                break;
2267            }
2268            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2269                try {
2270                    Locale l = (Locale) msg.obj;
2271                    IBinder service = ServiceManager.getService("mount");
2272                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2273                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2274                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2275                } catch (RemoteException e) {
2276                    Log.e(TAG, "Error storing locale for decryption UI", e);
2277                }
2278                break;
2279            }
2280            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2281                final int uid = msg.arg1;
2282                final byte[] firstPacket = (byte[]) msg.obj;
2283
2284                synchronized (mPidsSelfLocked) {
2285                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2286                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2287                        if (p.uid == uid) {
2288                            try {
2289                                p.thread.notifyCleartextNetwork(firstPacket);
2290                            } catch (RemoteException ignored) {
2291                            }
2292                        }
2293                    }
2294                }
2295                break;
2296            }
2297            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2298                final String procName;
2299                final int uid;
2300                final long memLimit;
2301                final String reportPackage;
2302                synchronized (ActivityManagerService.this) {
2303                    procName = mMemWatchDumpProcName;
2304                    uid = mMemWatchDumpUid;
2305                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2306                    if (val == null) {
2307                        val = mMemWatchProcesses.get(procName, 0);
2308                    }
2309                    if (val != null) {
2310                        memLimit = val.first;
2311                        reportPackage = val.second;
2312                    } else {
2313                        memLimit = 0;
2314                        reportPackage = null;
2315                    }
2316                }
2317                if (procName == null) {
2318                    return;
2319                }
2320
2321                if (DEBUG_PSS) Slog.d(TAG_PSS,
2322                        "Showing dump heap notification from " + procName + "/" + uid);
2323
2324                INotificationManager inm = NotificationManager.getService();
2325                if (inm == null) {
2326                    return;
2327                }
2328
2329                String text = mContext.getString(R.string.dump_heap_notification, procName);
2330
2331
2332                Intent deleteIntent = new Intent();
2333                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2334                Intent intent = new Intent();
2335                intent.setClassName("android", DumpHeapActivity.class.getName());
2336                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2337                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2338                if (reportPackage != null) {
2339                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2340                }
2341                int userId = UserHandle.getUserId(uid);
2342                Notification notification =
2343                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2344                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2345                        .setWhen(0)
2346                        .setOngoing(true)
2347                        .setAutoCancel(true)
2348                        .setTicker(text)
2349                        .setColor(mContext.getColor(
2350                                com.android.internal.R.color.system_notification_accent_color))
2351                        .setContentTitle(text)
2352                        .setContentText(
2353                                mContext.getText(R.string.dump_heap_notification_detail))
2354                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2355                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2356                                new UserHandle(userId)))
2357                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2358                                deleteIntent, 0, UserHandle.SYSTEM))
2359                        .build();
2360
2361                try {
2362                    inm.enqueueNotificationWithTag("android", "android", null,
2363                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2364                            notification, userId);
2365                } catch (RuntimeException e) {
2366                    Slog.w(ActivityManagerService.TAG,
2367                            "Error showing notification for dump heap", e);
2368                } catch (RemoteException e) {
2369                }
2370            } break;
2371            case DELETE_DUMPHEAP_MSG: {
2372                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2373                        null, DumpHeapActivity.JAVA_URI,
2374                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2375                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2376                        UserHandle.myUserId());
2377                synchronized (ActivityManagerService.this) {
2378                    mMemWatchDumpFile = null;
2379                    mMemWatchDumpProcName = null;
2380                    mMemWatchDumpPid = -1;
2381                    mMemWatchDumpUid = -1;
2382                }
2383            } break;
2384            case REPORT_TIME_TRACKER_MSG: {
2385                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2386                tracker.deliverResult(mContext);
2387            } break;
2388            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2389                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2390                try {
2391                    connection.shutdown();
2392                } catch (RemoteException e) {
2393                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2394                }
2395                // Only a UiAutomation can set this flag and now that
2396                // it is finished we make sure it is reset to its default.
2397                mUserIsMonkey = false;
2398            } break;
2399            case IDLE_UIDS_MSG: {
2400                idleUids();
2401            } break;
2402            case VR_MODE_CHANGE_MSG: {
2403                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2404                    return;
2405                }
2406                synchronized (ActivityManagerService.this) {
2407                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2408                    mWindowManager.disableNonVrUi(disableNonVrUi);
2409                    if (disableNonVrUi) {
2410                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2411                        // then remove the pinned stack.
2412                        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2413                    }
2414                }
2415            } break;
2416            case DISPATCH_SCREEN_AWAKE_MSG: {
2417                final boolean isAwake = msg.arg1 != 0;
2418                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2419                    mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2420                }
2421            } break;
2422            case DISPATCH_SCREEN_KEYGUARD_MSG: {
2423                final boolean isShowing = msg.arg1 != 0;
2424                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2425                    mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2426                }
2427            } break;
2428            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2429                synchronized (ActivityManagerService.this) {
2430                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2431                        ProcessRecord r = mLruProcesses.get(i);
2432                        if (r.thread != null) {
2433                            try {
2434                                r.thread.handleTrustStorageUpdate();
2435                            } catch (RemoteException ex) {
2436                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2437                                        r.info.processName);
2438                            }
2439                        }
2440                    }
2441                }
2442            } break;
2443            }
2444        }
2445    };
2446
2447    static final int COLLECT_PSS_BG_MSG = 1;
2448
2449    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2450        @Override
2451        public void handleMessage(Message msg) {
2452            switch (msg.what) {
2453            case COLLECT_PSS_BG_MSG: {
2454                long start = SystemClock.uptimeMillis();
2455                MemInfoReader memInfo = null;
2456                synchronized (ActivityManagerService.this) {
2457                    if (mFullPssPending) {
2458                        mFullPssPending = false;
2459                        memInfo = new MemInfoReader();
2460                    }
2461                }
2462                if (memInfo != null) {
2463                    updateCpuStatsNow();
2464                    long nativeTotalPss = 0;
2465                    final List<ProcessCpuTracker.Stats> stats;
2466                    synchronized (mProcessCpuTracker) {
2467                        stats = mProcessCpuTracker.getStats( (st)-> {
2468                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2469                        });
2470                    }
2471                    final int N = stats.size();
2472                    for (int j = 0; j < N; j++) {
2473                        synchronized (mPidsSelfLocked) {
2474                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2475                                // This is one of our own processes; skip it.
2476                                continue;
2477                            }
2478                        }
2479                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2480                    }
2481                    memInfo.readMemInfo();
2482                    synchronized (ActivityManagerService.this) {
2483                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2484                                + (SystemClock.uptimeMillis()-start) + "ms");
2485                        final long cachedKb = memInfo.getCachedSizeKb();
2486                        final long freeKb = memInfo.getFreeSizeKb();
2487                        final long zramKb = memInfo.getZramTotalSizeKb();
2488                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2489                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2490                                kernelKb*1024, nativeTotalPss*1024);
2491                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2492                                nativeTotalPss);
2493                    }
2494                }
2495
2496                int num = 0;
2497                long[] tmp = new long[2];
2498                do {
2499                    ProcessRecord proc;
2500                    int procState;
2501                    int pid;
2502                    long lastPssTime;
2503                    synchronized (ActivityManagerService.this) {
2504                        if (mPendingPssProcesses.size() <= 0) {
2505                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2506                                    "Collected PSS of " + num + " processes in "
2507                                    + (SystemClock.uptimeMillis() - start) + "ms");
2508                            mPendingPssProcesses.clear();
2509                            return;
2510                        }
2511                        proc = mPendingPssProcesses.remove(0);
2512                        procState = proc.pssProcState;
2513                        lastPssTime = proc.lastPssTime;
2514                        if (proc.thread != null && procState == proc.setProcState
2515                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2516                                        < SystemClock.uptimeMillis()) {
2517                            pid = proc.pid;
2518                        } else {
2519                            proc = null;
2520                            pid = 0;
2521                        }
2522                    }
2523                    if (proc != null) {
2524                        long startTime = SystemClock.currentThreadTimeMillis();
2525                        long pss = Debug.getPss(pid, tmp, null);
2526                        long endTime = SystemClock.currentThreadTimeMillis();
2527                        synchronized (ActivityManagerService.this) {
2528                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2529                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2530                                num++;
2531                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2532                                        endTime-startTime, SystemClock.uptimeMillis());
2533                            }
2534                        }
2535                    }
2536                } while (true);
2537            }
2538            }
2539        }
2540    };
2541
2542    public void setSystemProcess() {
2543        try {
2544            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
2545                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
2546            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2547            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
2548                    DUMP_FLAG_PRIORITY_HIGH);
2549            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2550            ServiceManager.addService("dbinfo", new DbBinder(this));
2551            if (MONITOR_CPU_USAGE) {
2552                ServiceManager.addService("cpuinfo", new CpuBinder(this),
2553                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
2554            }
2555            ServiceManager.addService("permission", new PermissionController(this));
2556            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2557
2558            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2559                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2560            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2561
2562            synchronized (this) {
2563                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2564                app.persistent = true;
2565                app.pid = MY_PID;
2566                app.maxAdj = ProcessList.SYSTEM_ADJ;
2567                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2568                synchronized (mPidsSelfLocked) {
2569                    mPidsSelfLocked.put(app.pid, app);
2570                }
2571                updateLruProcessLocked(app, false, null);
2572                updateOomAdjLocked();
2573            }
2574        } catch (PackageManager.NameNotFoundException e) {
2575            throw new RuntimeException(
2576                    "Unable to find android system package", e);
2577        }
2578    }
2579
2580    public void setWindowManager(WindowManagerService wm) {
2581        synchronized (this) {
2582            mWindowManager = wm;
2583            mStackSupervisor.setWindowManager(wm);
2584            mLockTaskController.setWindowManager(wm);
2585        }
2586    }
2587
2588    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2589        mUsageStatsService = usageStatsManager;
2590    }
2591
2592    public void startObservingNativeCrashes() {
2593        final NativeCrashListener ncl = new NativeCrashListener(this);
2594        ncl.start();
2595    }
2596
2597    public IAppOpsService getAppOpsService() {
2598        return mAppOpsService;
2599    }
2600
2601    static class MemBinder extends Binder {
2602        ActivityManagerService mActivityManagerService;
2603        private final PriorityDump.PriorityDumper mPriorityDumper =
2604                new PriorityDump.PriorityDumper() {
2605            @Override
2606            public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args,
2607                    boolean asProto) {
2608                dump(fd, pw, new String[] {"-a"}, asProto);
2609            }
2610
2611            @Override
2612            public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
2613                mActivityManagerService.dumpApplicationMemoryUsage(
2614                        fd, pw, "  ", args, false, null, asProto);
2615            }
2616        };
2617
2618        MemBinder(ActivityManagerService activityManagerService) {
2619            mActivityManagerService = activityManagerService;
2620        }
2621
2622        @Override
2623        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2624            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2625                    "meminfo", pw)) return;
2626            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2627        }
2628    }
2629
2630    static class GraphicsBinder extends Binder {
2631        ActivityManagerService mActivityManagerService;
2632        GraphicsBinder(ActivityManagerService activityManagerService) {
2633            mActivityManagerService = activityManagerService;
2634        }
2635
2636        @Override
2637        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2638            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2639                    "gfxinfo", pw)) return;
2640            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2641        }
2642    }
2643
2644    static class DbBinder extends Binder {
2645        ActivityManagerService mActivityManagerService;
2646        DbBinder(ActivityManagerService activityManagerService) {
2647            mActivityManagerService = activityManagerService;
2648        }
2649
2650        @Override
2651        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2652            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2653                    "dbinfo", pw)) return;
2654            mActivityManagerService.dumpDbInfo(fd, pw, args);
2655        }
2656    }
2657
2658    static class CpuBinder extends Binder {
2659        ActivityManagerService mActivityManagerService;
2660        private final PriorityDump.PriorityDumper mPriorityDumper =
2661                new PriorityDump.PriorityDumper() {
2662            @Override
2663            public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
2664                    boolean asProto) {
2665                if (asProto) return;
2666                if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2667                        "cpuinfo", pw)) return;
2668                synchronized (mActivityManagerService.mProcessCpuTracker) {
2669                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2670                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2671                            SystemClock.uptimeMillis()));
2672                }
2673            }
2674        };
2675
2676        CpuBinder(ActivityManagerService activityManagerService) {
2677            mActivityManagerService = activityManagerService;
2678        }
2679
2680        @Override
2681        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2682            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2683        }
2684    }
2685
2686    public static final class Lifecycle extends SystemService {
2687        private final ActivityManagerService mService;
2688
2689        public Lifecycle(Context context) {
2690            super(context);
2691            mService = new ActivityManagerService(context);
2692        }
2693
2694        @Override
2695        public void onStart() {
2696            mService.start();
2697        }
2698
2699        @Override
2700        public void onBootPhase(int phase) {
2701            if (phase == PHASE_SYSTEM_SERVICES_READY) {
2702                mService.mBatteryStatsService.systemServicesReady();
2703            }
2704        }
2705
2706        @Override
2707        public void onCleanupUser(int userId) {
2708            mService.mBatteryStatsService.onCleanupUser(userId);
2709        }
2710
2711        public ActivityManagerService getService() {
2712            return mService;
2713        }
2714    }
2715
2716    @VisibleForTesting
2717    public ActivityManagerService(Injector injector) {
2718        mInjector = injector;
2719        mContext = mInjector.getContext();
2720        mUiContext = null;
2721        GL_ES_VERSION = 0;
2722        mActivityStartController = null;
2723        mAppErrors = null;
2724        mAppWarnings = null;
2725        mAppOpsService = mInjector.getAppOpsService(null, null);
2726        mBatteryStatsService = null;
2727        mCompatModePackages = null;
2728        mConstants = null;
2729        mGrantFile = null;
2730        mHandler = null;
2731        mHandlerThread = null;
2732        mIntentFirewall = null;
2733        mKeyguardController = null;
2734        mPermissionReviewRequired = false;
2735        mProcessCpuThread = null;
2736        mProcessStats = null;
2737        mProviderMap = null;
2738        mRecentTasks = null;
2739        mServices = null;
2740        mStackSupervisor = null;
2741        mSystemThread = null;
2742        mTaskChangeNotificationController = null;
2743        mUiHandler = injector.getUiHandler(null);
2744        mUserController = null;
2745        mVrController = null;
2746        mLockTaskController = null;
2747        mLifecycleManager = null;
2748        mProcStartHandlerThread = null;
2749        mProcStartHandler = null;
2750    }
2751
2752    // Note: This method is invoked on the main thread but may need to attach various
2753    // handlers to other threads.  So take care to be explicit about the looper.
2754    public ActivityManagerService(Context systemContext) {
2755        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2756        mInjector = new Injector();
2757        mContext = systemContext;
2758
2759        mFactoryTest = FactoryTest.getMode();
2760        mSystemThread = ActivityThread.currentActivityThread();
2761        mUiContext = mSystemThread.getSystemUiContext();
2762
2763        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2764
2765        mPermissionReviewRequired = mContext.getResources().getBoolean(
2766                com.android.internal.R.bool.config_permissionReviewRequired);
2767
2768        mHandlerThread = new ServiceThread(TAG,
2769                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2770        mHandlerThread.start();
2771        mHandler = new MainHandler(mHandlerThread.getLooper());
2772        mUiHandler = mInjector.getUiHandler(this);
2773
2774        mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
2775                THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
2776        mProcStartHandlerThread.start();
2777        mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
2778
2779        mConstants = new ActivityManagerConstants(this, mHandler);
2780
2781        /* static; one-time init here */
2782        if (sKillHandler == null) {
2783            sKillThread = new ServiceThread(TAG + ":kill",
2784                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2785            sKillThread.start();
2786            sKillHandler = new KillHandler(sKillThread.getLooper());
2787        }
2788
2789        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2790                "foreground", BROADCAST_FG_TIMEOUT, false);
2791        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2792                "background", BROADCAST_BG_TIMEOUT, true);
2793        mBroadcastQueues[0] = mFgBroadcastQueue;
2794        mBroadcastQueues[1] = mBgBroadcastQueue;
2795
2796        mServices = new ActiveServices(this);
2797        mProviderMap = new ProviderMap(this);
2798        mAppErrors = new AppErrors(mUiContext, this);
2799
2800        File dataDir = Environment.getDataDirectory();
2801        File systemDir = new File(dataDir, "system");
2802        systemDir.mkdirs();
2803
2804        mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
2805
2806        // TODO: Move creation of battery stats service outside of activity manager service.
2807        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2808        mBatteryStatsService.getActiveStatistics().readLocked();
2809        mBatteryStatsService.scheduleWriteToDisk();
2810        mOnBattery = DEBUG_POWER ? true
2811                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2812        mBatteryStatsService.getActiveStatistics().setCallback(this);
2813
2814        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2815
2816        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2817        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2818                new IAppOpsCallback.Stub() {
2819                    @Override public void opChanged(int op, int uid, String packageName) {
2820                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2821                            if (mAppOpsService.checkOperation(op, uid, packageName)
2822                                    != AppOpsManager.MODE_ALLOWED) {
2823                                runInBackgroundDisabled(uid);
2824                            }
2825                        }
2826                    }
2827                });
2828
2829        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2830
2831        mUserController = new UserController(this);
2832
2833        mVrController = new VrController(this);
2834
2835        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2836            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2837
2838        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2839            mUseFifoUiScheduling = true;
2840        }
2841
2842        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2843        mTempConfig.setToDefaults();
2844        mTempConfig.setLocales(LocaleList.getDefault());
2845        mConfigurationSeq = mTempConfig.seq = 1;
2846        mStackSupervisor = createStackSupervisor();
2847        mStackSupervisor.onConfigurationChanged(mTempConfig);
2848        mKeyguardController = mStackSupervisor.getKeyguardController();
2849        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2850        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2851        mTaskChangeNotificationController =
2852                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2853        mActivityStartController = new ActivityStartController(this);
2854        mRecentTasks = createRecentTasks();
2855        mStackSupervisor.setRecentTasks(mRecentTasks);
2856        mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
2857        mLifecycleManager = new ClientLifecycleManager();
2858
2859        mProcessCpuThread = new Thread("CpuTracker") {
2860            @Override
2861            public void run() {
2862                synchronized (mProcessCpuTracker) {
2863                    mProcessCpuInitLatch.countDown();
2864                    mProcessCpuTracker.init();
2865                }
2866                while (true) {
2867                    try {
2868                        try {
2869                            synchronized(this) {
2870                                final long now = SystemClock.uptimeMillis();
2871                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2872                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2873                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2874                                //        + ", write delay=" + nextWriteDelay);
2875                                if (nextWriteDelay < nextCpuDelay) {
2876                                    nextCpuDelay = nextWriteDelay;
2877                                }
2878                                if (nextCpuDelay > 0) {
2879                                    mProcessCpuMutexFree.set(true);
2880                                    this.wait(nextCpuDelay);
2881                                }
2882                            }
2883                        } catch (InterruptedException e) {
2884                        }
2885                        updateCpuStatsNow();
2886                    } catch (Exception e) {
2887                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2888                    }
2889                }
2890            }
2891        };
2892
2893        Watchdog.getInstance().addMonitor(this);
2894        Watchdog.getInstance().addThread(mHandler);
2895    }
2896
2897    protected ActivityStackSupervisor createStackSupervisor() {
2898        final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
2899        supervisor.initialize();
2900        return supervisor;
2901    }
2902
2903    protected RecentTasks createRecentTasks() {
2904        return new RecentTasks(this, mStackSupervisor);
2905    }
2906
2907    RecentTasks getRecentTasks() {
2908        return mRecentTasks;
2909    }
2910
2911    public void setSystemServiceManager(SystemServiceManager mgr) {
2912        mSystemServiceManager = mgr;
2913    }
2914
2915    public void setInstaller(Installer installer) {
2916        mInstaller = installer;
2917    }
2918
2919    private void start() {
2920        removeAllProcessGroups();
2921        mProcessCpuThread.start();
2922
2923        mBatteryStatsService.publish();
2924        mAppOpsService.publish(mContext);
2925        Slog.d("AppOps", "AppOpsService published");
2926        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2927        // Wait for the synchronized block started in mProcessCpuThread,
2928        // so that any other acccess to mProcessCpuTracker from main thread
2929        // will be blocked during mProcessCpuTracker initialization.
2930        try {
2931            mProcessCpuInitLatch.await();
2932        } catch (InterruptedException e) {
2933            Slog.wtf(TAG, "Interrupted wait during start", e);
2934            Thread.currentThread().interrupt();
2935            throw new IllegalStateException("Interrupted wait during start");
2936        }
2937    }
2938
2939    void onUserStoppedLocked(int userId) {
2940        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2941        mAllowAppSwitchUids.remove(userId);
2942    }
2943
2944    public void initPowerManagement() {
2945        mStackSupervisor.initPowerManagement();
2946        mBatteryStatsService.initPowerManagement();
2947        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2948        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2949        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2950        mVoiceWakeLock.setReferenceCounted(false);
2951    }
2952
2953    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2954        if (mBackgroundLaunchBroadcasts == null) {
2955            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2956        }
2957        return mBackgroundLaunchBroadcasts;
2958    }
2959
2960    @Override
2961    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2962            throws RemoteException {
2963        if (code == SYSPROPS_TRANSACTION) {
2964            // We need to tell all apps about the system property change.
2965            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2966            synchronized(this) {
2967                final int NP = mProcessNames.getMap().size();
2968                for (int ip=0; ip<NP; ip++) {
2969                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2970                    final int NA = apps.size();
2971                    for (int ia=0; ia<NA; ia++) {
2972                        ProcessRecord app = apps.valueAt(ia);
2973                        if (app.thread != null) {
2974                            procs.add(app.thread.asBinder());
2975                        }
2976                    }
2977                }
2978            }
2979
2980            int N = procs.size();
2981            for (int i=0; i<N; i++) {
2982                Parcel data2 = Parcel.obtain();
2983                try {
2984                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2985                            Binder.FLAG_ONEWAY);
2986                } catch (RemoteException e) {
2987                }
2988                data2.recycle();
2989            }
2990        }
2991        try {
2992            return super.onTransact(code, data, reply, flags);
2993        } catch (RuntimeException e) {
2994            // The activity manager only throws certain exceptions intentionally, so let's
2995            // log all others.
2996            if (!(e instanceof SecurityException
2997                    || e instanceof IllegalArgumentException
2998                    || e instanceof IllegalStateException)) {
2999                Slog.wtf(TAG, "Activity Manager Crash."
3000                        + " UID:" + Binder.getCallingUid()
3001                        + " PID:" + Binder.getCallingPid()
3002                        + " TRANS:" + code, e);
3003            }
3004            throw e;
3005        }
3006    }
3007
3008    void updateCpuStats() {
3009        final long now = SystemClock.uptimeMillis();
3010        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
3011            return;
3012        }
3013        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
3014            synchronized (mProcessCpuThread) {
3015                mProcessCpuThread.notify();
3016            }
3017        }
3018    }
3019
3020    void updateCpuStatsNow() {
3021        synchronized (mProcessCpuTracker) {
3022            mProcessCpuMutexFree.set(false);
3023            final long now = SystemClock.uptimeMillis();
3024            boolean haveNewCpuStats = false;
3025
3026            if (MONITOR_CPU_USAGE &&
3027                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
3028                mLastCpuTime.set(now);
3029                mProcessCpuTracker.update();
3030                if (mProcessCpuTracker.hasGoodLastStats()) {
3031                    haveNewCpuStats = true;
3032                    //Slog.i(TAG, mProcessCpu.printCurrentState());
3033                    //Slog.i(TAG, "Total CPU usage: "
3034                    //        + mProcessCpu.getTotalCpuPercent() + "%");
3035
3036                    // Slog the cpu usage if the property is set.
3037                    if ("true".equals(SystemProperties.get("events.cpu"))) {
3038                        int user = mProcessCpuTracker.getLastUserTime();
3039                        int system = mProcessCpuTracker.getLastSystemTime();
3040                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
3041                        int irq = mProcessCpuTracker.getLastIrqTime();
3042                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
3043                        int idle = mProcessCpuTracker.getLastIdleTime();
3044
3045                        int total = user + system + iowait + irq + softIrq + idle;
3046                        if (total == 0) total = 1;
3047
3048                        EventLog.writeEvent(EventLogTags.CPU,
3049                                ((user+system+iowait+irq+softIrq) * 100) / total,
3050                                (user * 100) / total,
3051                                (system * 100) / total,
3052                                (iowait * 100) / total,
3053                                (irq * 100) / total,
3054                                (softIrq * 100) / total);
3055                    }
3056                }
3057            }
3058
3059            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3060            synchronized(bstats) {
3061                synchronized(mPidsSelfLocked) {
3062                    if (haveNewCpuStats) {
3063                        if (bstats.startAddingCpuLocked()) {
3064                            int totalUTime = 0;
3065                            int totalSTime = 0;
3066                            final int N = mProcessCpuTracker.countStats();
3067                            for (int i=0; i<N; i++) {
3068                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3069                                if (!st.working) {
3070                                    continue;
3071                                }
3072                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3073                                totalUTime += st.rel_utime;
3074                                totalSTime += st.rel_stime;
3075                                if (pr != null) {
3076                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3077                                    if (ps == null || !ps.isActive()) {
3078                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3079                                                pr.info.uid, pr.processName);
3080                                    }
3081                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3082                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3083                                    if (pr.lastCpuTime == 0) {
3084                                        pr.lastCpuTime = pr.curCpuTime;
3085                                    }
3086                                } else {
3087                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3088                                    if (ps == null || !ps.isActive()) {
3089                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3090                                                bstats.mapUid(st.uid), st.name);
3091                                    }
3092                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3093                                }
3094                            }
3095                            final int userTime = mProcessCpuTracker.getLastUserTime();
3096                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3097                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3098                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3099                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3100                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3101                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3102                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3103                        }
3104                    }
3105                }
3106
3107                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3108                    mLastWriteTime = now;
3109                    mBatteryStatsService.scheduleWriteToDisk();
3110                }
3111            }
3112        }
3113    }
3114
3115    @Override
3116    public void batteryNeedsCpuUpdate() {
3117        updateCpuStatsNow();
3118    }
3119
3120    @Override
3121    public void batteryPowerChanged(boolean onBattery) {
3122        // When plugging in, update the CPU stats first before changing
3123        // the plug state.
3124        updateCpuStatsNow();
3125        synchronized (this) {
3126            synchronized(mPidsSelfLocked) {
3127                mOnBattery = DEBUG_POWER ? true : onBattery;
3128            }
3129        }
3130    }
3131
3132    @Override
3133    public void batterySendBroadcast(Intent intent) {
3134        synchronized (this) {
3135            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3136                    OP_NONE, null, false, false,
3137                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3138        }
3139    }
3140
3141    /**
3142     * Initialize the application bind args. These are passed to each
3143     * process when the bindApplication() IPC is sent to the process. They're
3144     * lazily setup to make sure the services are running when they're asked for.
3145     */
3146    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3147        // Isolated processes won't get this optimization, so that we don't
3148        // violate the rules about which services they have access to.
3149        if (isolated) {
3150            if (mIsolatedAppBindArgs == null) {
3151                mIsolatedAppBindArgs = new HashMap<>();
3152                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3153            }
3154            return mIsolatedAppBindArgs;
3155        }
3156
3157        if (mAppBindArgs == null) {
3158            mAppBindArgs = new HashMap<>();
3159
3160            // Setup the application init args
3161            mAppBindArgs.put("package", ServiceManager.getService("package"));
3162            mAppBindArgs.put("window", ServiceManager.getService("window"));
3163            mAppBindArgs.put(Context.ALARM_SERVICE,
3164                    ServiceManager.getService(Context.ALARM_SERVICE));
3165        }
3166        return mAppBindArgs;
3167    }
3168
3169    /**
3170     * Update AMS states when an activity is resumed. This should only be called by
3171     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3172     */
3173    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3174        final TaskRecord task = r.getTask();
3175        if (task.isActivityTypeStandard()) {
3176            if (mCurAppTimeTracker != r.appTimeTracker) {
3177                // We are switching app tracking.  Complete the current one.
3178                if (mCurAppTimeTracker != null) {
3179                    mCurAppTimeTracker.stop();
3180                    mHandler.obtainMessage(
3181                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3182                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3183                    mCurAppTimeTracker = null;
3184                }
3185                if (r.appTimeTracker != null) {
3186                    mCurAppTimeTracker = r.appTimeTracker;
3187                    startTimeTrackingFocusedActivityLocked();
3188                }
3189            } else {
3190                startTimeTrackingFocusedActivityLocked();
3191            }
3192        } else {
3193            r.appTimeTracker = null;
3194        }
3195        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3196        // TODO: Probably not, because we don't want to resume voice on switching
3197        // back to this activity
3198        if (task.voiceInteractor != null) {
3199            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3200        } else {
3201            finishRunningVoiceLocked();
3202
3203            if (mLastResumedActivity != null) {
3204                final IVoiceInteractionSession session;
3205
3206                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3207                if (lastResumedActivityTask != null
3208                        && lastResumedActivityTask.voiceSession != null) {
3209                    session = lastResumedActivityTask.voiceSession;
3210                } else {
3211                    session = mLastResumedActivity.voiceSession;
3212                }
3213
3214                if (session != null) {
3215                    // We had been in a voice interaction session, but now focused has
3216                    // move to something different.  Just finish the session, we can't
3217                    // return to it and retain the proper state and synchronization with
3218                    // the voice interaction service.
3219                    finishVoiceTask(session);
3220                }
3221            }
3222        }
3223
3224        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3225            mUserController.sendForegroundProfileChanged(r.userId);
3226        }
3227        mLastResumedActivity = r;
3228
3229        mWindowManager.setFocusedApp(r.appToken, true);
3230
3231        applyUpdateLockStateLocked(r);
3232        applyUpdateVrModeLocked(r);
3233
3234        EventLogTags.writeAmSetResumedActivity(
3235                r == null ? -1 : r.userId,
3236                r == null ? "NULL" : r.shortComponentName,
3237                reason);
3238    }
3239
3240    @Override
3241    public void setFocusedStack(int stackId) {
3242        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3243        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3244        final long callingId = Binder.clearCallingIdentity();
3245        try {
3246            synchronized (this) {
3247                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3248                if (stack == null) {
3249                    Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
3250                    return;
3251                }
3252                final ActivityRecord r = stack.topRunningActivityLocked();
3253                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3254                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3255                }
3256            }
3257        } finally {
3258            Binder.restoreCallingIdentity(callingId);
3259        }
3260    }
3261
3262    @Override
3263    public void setFocusedTask(int taskId) {
3264        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3265        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3266        final long callingId = Binder.clearCallingIdentity();
3267        try {
3268            synchronized (this) {
3269                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3270                if (task == null) {
3271                    return;
3272                }
3273                final ActivityRecord r = task.topRunningActivityLocked();
3274                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3275                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3276                }
3277            }
3278        } finally {
3279            Binder.restoreCallingIdentity(callingId);
3280        }
3281    }
3282
3283    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3284    @Override
3285    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3286        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3287                "registerTaskStackListener()");
3288        mTaskChangeNotificationController.registerTaskStackListener(listener);
3289    }
3290
3291    /**
3292     * Unregister a task stack listener so that it stops receiving callbacks.
3293     */
3294    @Override
3295    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3296        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3297                "unregisterTaskStackListener()");
3298         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3299     }
3300
3301    @Override
3302    public void notifyActivityDrawn(IBinder token) {
3303        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3304        synchronized (this) {
3305            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3306            if (r != null) {
3307                r.getStack().notifyActivityDrawnLocked(r);
3308            }
3309        }
3310    }
3311
3312    final void applyUpdateLockStateLocked(ActivityRecord r) {
3313        // Modifications to the UpdateLock state are done on our handler, outside
3314        // the activity manager's locks.  The new state is determined based on the
3315        // state *now* of the relevant activity record.  The object is passed to
3316        // the handler solely for logging detail, not to be consulted/modified.
3317        final boolean nextState = r != null && r.immersive;
3318        mHandler.sendMessage(
3319                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3320    }
3321
3322    final void applyUpdateVrModeLocked(ActivityRecord r) {
3323        // VR apps are expected to run in a main display. If an app is turning on VR for
3324        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3325        // fullscreen stack before enabling VR Mode.
3326        // TODO: The goal of this code is to keep the VR app on the main display. When the
3327        // stack implementation changes in the future, keep in mind that the use of the fullscreen
3328        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3329        // option would be a better choice here.
3330        if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3331            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3332                    + " to main stack for VR");
3333            final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3334                    WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3335            moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3336        }
3337        mHandler.sendMessage(
3338                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3339    }
3340
3341    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3342        Message msg = Message.obtain();
3343        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3344        msg.obj = r.getTask().askedCompatMode ? null : r;
3345        mUiHandler.sendMessage(msg);
3346    }
3347
3348    final AppWarnings getAppWarningsLocked() {
3349        return mAppWarnings;
3350    }
3351
3352    /**
3353     * Shows app warning dialogs, if necessary.
3354     *
3355     * @param r activity record for which the warnings may be displayed
3356     */
3357    final void showAppWarningsIfNeededLocked(ActivityRecord r) {
3358        mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
3359        mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
3360    }
3361
3362    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3363            String what, Object obj, ProcessRecord srcApp) {
3364        app.lastActivityTime = now;
3365
3366        if (app.activities.size() > 0 || app.recentTasks.size() > 0) {
3367            // Don't want to touch dependent processes that are hosting activities.
3368            return index;
3369        }
3370
3371        int lrui = mLruProcesses.lastIndexOf(app);
3372        if (lrui < 0) {
3373            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3374                    + what + " " + obj + " from " + srcApp);
3375            return index;
3376        }
3377
3378        if (lrui >= index) {
3379            // Don't want to cause this to move dependent processes *back* in the
3380            // list as if they were less frequently used.
3381            return index;
3382        }
3383
3384        if (lrui >= mLruProcessActivityStart) {
3385            // Don't want to touch dependent processes that are hosting activities.
3386            return index;
3387        }
3388
3389        mLruProcesses.remove(lrui);
3390        if (index > 0) {
3391            index--;
3392        }
3393        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3394                + " in LRU list: " + app);
3395        mLruProcesses.add(index, app);
3396        return index;
3397    }
3398
3399    static void killProcessGroup(int uid, int pid) {
3400        if (sKillHandler != null) {
3401            sKillHandler.sendMessage(
3402                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3403        } else {
3404            Slog.w(TAG, "Asked to kill process group before system bringup!");
3405            Process.killProcessGroup(uid, pid);
3406        }
3407    }
3408
3409    final void removeLruProcessLocked(ProcessRecord app) {
3410        int lrui = mLruProcesses.lastIndexOf(app);
3411        if (lrui >= 0) {
3412            if (!app.killed) {
3413                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3414                if (app.pid > 0) {
3415                    killProcessQuiet(app.pid);
3416                    killProcessGroup(app.uid, app.pid);
3417                } else {
3418                    app.pendingStart = false;
3419                }
3420            }
3421            if (lrui <= mLruProcessActivityStart) {
3422                mLruProcessActivityStart--;
3423            }
3424            if (lrui <= mLruProcessServiceStart) {
3425                mLruProcessServiceStart--;
3426            }
3427            mLruProcesses.remove(lrui);
3428        }
3429    }
3430
3431    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3432            ProcessRecord client) {
3433        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3434                || app.treatLikeActivity || app.recentTasks.size() > 0;
3435        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3436        if (!activityChange && hasActivity) {
3437            // The process has activities, so we are only allowing activity-based adjustments
3438            // to move it.  It should be kept in the front of the list with other
3439            // processes that have activities, and we don't want those to change their
3440            // order except due to activity operations.
3441            return;
3442        }
3443
3444        mLruSeq++;
3445        final long now = SystemClock.uptimeMillis();
3446        app.lastActivityTime = now;
3447
3448        // First a quick reject: if the app is already at the position we will
3449        // put it, then there is nothing to do.
3450        if (hasActivity) {
3451            final int N = mLruProcesses.size();
3452            if (N > 0 && mLruProcesses.get(N-1) == app) {
3453                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3454                return;
3455            }
3456        } else {
3457            if (mLruProcessServiceStart > 0
3458                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3459                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3460                return;
3461            }
3462        }
3463
3464        int lrui = mLruProcesses.lastIndexOf(app);
3465
3466        if (app.persistent && lrui >= 0) {
3467            // We don't care about the position of persistent processes, as long as
3468            // they are in the list.
3469            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3470            return;
3471        }
3472
3473        /* In progress: compute new position first, so we can avoid doing work
3474           if the process is not actually going to move.  Not yet working.
3475        int addIndex;
3476        int nextIndex;
3477        boolean inActivity = false, inService = false;
3478        if (hasActivity) {
3479            // Process has activities, put it at the very tipsy-top.
3480            addIndex = mLruProcesses.size();
3481            nextIndex = mLruProcessServiceStart;
3482            inActivity = true;
3483        } else if (hasService) {
3484            // Process has services, put it at the top of the service list.
3485            addIndex = mLruProcessActivityStart;
3486            nextIndex = mLruProcessServiceStart;
3487            inActivity = true;
3488            inService = true;
3489        } else  {
3490            // Process not otherwise of interest, it goes to the top of the non-service area.
3491            addIndex = mLruProcessServiceStart;
3492            if (client != null) {
3493                int clientIndex = mLruProcesses.lastIndexOf(client);
3494                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3495                        + app);
3496                if (clientIndex >= 0 && addIndex > clientIndex) {
3497                    addIndex = clientIndex;
3498                }
3499            }
3500            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3501        }
3502
3503        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3504                + mLruProcessActivityStart + "): " + app);
3505        */
3506
3507        if (lrui >= 0) {
3508            if (lrui < mLruProcessActivityStart) {
3509                mLruProcessActivityStart--;
3510            }
3511            if (lrui < mLruProcessServiceStart) {
3512                mLruProcessServiceStart--;
3513            }
3514            /*
3515            if (addIndex > lrui) {
3516                addIndex--;
3517            }
3518            if (nextIndex > lrui) {
3519                nextIndex--;
3520            }
3521            */
3522            mLruProcesses.remove(lrui);
3523        }
3524
3525        /*
3526        mLruProcesses.add(addIndex, app);
3527        if (inActivity) {
3528            mLruProcessActivityStart++;
3529        }
3530        if (inService) {
3531            mLruProcessActivityStart++;
3532        }
3533        */
3534
3535        int nextIndex;
3536        if (hasActivity) {
3537            final int N = mLruProcesses.size();
3538            if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
3539                    && mLruProcessActivityStart < (N - 1)) {
3540                // Process doesn't have activities, but has clients with
3541                // activities...  move it up, but one below the top (the top
3542                // should always have a real activity).
3543                if (DEBUG_LRU) Slog.d(TAG_LRU,
3544                        "Adding to second-top of LRU activity list: " + app);
3545                mLruProcesses.add(N - 1, app);
3546                // To keep it from spamming the LRU list (by making a bunch of clients),
3547                // we will push down any other entries owned by the app.
3548                final int uid = app.info.uid;
3549                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3550                    ProcessRecord subProc = mLruProcesses.get(i);
3551                    if (subProc.info.uid == uid) {
3552                        // We want to push this one down the list.  If the process after
3553                        // it is for the same uid, however, don't do so, because we don't
3554                        // want them internally to be re-ordered.
3555                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3556                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3557                                    "Pushing uid " + uid + " swapping at " + i + ": "
3558                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3559                            ProcessRecord tmp = mLruProcesses.get(i);
3560                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3561                            mLruProcesses.set(i - 1, tmp);
3562                            i--;
3563                        }
3564                    } else {
3565                        // A gap, we can stop here.
3566                        break;
3567                    }
3568                }
3569            } else {
3570                // Process has activities, put it at the very tipsy-top.
3571                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3572                mLruProcesses.add(app);
3573            }
3574            nextIndex = mLruProcessServiceStart;
3575        } else if (hasService) {
3576            // Process has services, put it at the top of the service list.
3577            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3578            mLruProcesses.add(mLruProcessActivityStart, app);
3579            nextIndex = mLruProcessServiceStart;
3580            mLruProcessActivityStart++;
3581        } else  {
3582            // Process not otherwise of interest, it goes to the top of the non-service area.
3583            int index = mLruProcessServiceStart;
3584            if (client != null) {
3585                // If there is a client, don't allow the process to be moved up higher
3586                // in the list than that client.
3587                int clientIndex = mLruProcesses.lastIndexOf(client);
3588                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3589                        + " when updating " + app);
3590                if (clientIndex <= lrui) {
3591                    // Don't allow the client index restriction to push it down farther in the
3592                    // list than it already is.
3593                    clientIndex = lrui;
3594                }
3595                if (clientIndex >= 0 && index > clientIndex) {
3596                    index = clientIndex;
3597                }
3598            }
3599            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3600            mLruProcesses.add(index, app);
3601            nextIndex = index-1;
3602            mLruProcessActivityStart++;
3603            mLruProcessServiceStart++;
3604        }
3605
3606        // If the app is currently using a content provider or service,
3607        // bump those processes as well.
3608        for (int j=app.connections.size()-1; j>=0; j--) {
3609            ConnectionRecord cr = app.connections.valueAt(j);
3610            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3611                    && cr.binding.service.app != null
3612                    && cr.binding.service.app.lruSeq != mLruSeq
3613                    && !cr.binding.service.app.persistent) {
3614                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3615                        "service connection", cr, app);
3616            }
3617        }
3618        for (int j=app.conProviders.size()-1; j>=0; j--) {
3619            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3620            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3621                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3622                        "provider reference", cpr, app);
3623            }
3624        }
3625    }
3626
3627    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3628        if (uid == SYSTEM_UID) {
3629            // The system gets to run in any process.  If there are multiple
3630            // processes with the same uid, just pick the first (this
3631            // should never happen).
3632            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3633            if (procs == null) return null;
3634            final int procCount = procs.size();
3635            for (int i = 0; i < procCount; i++) {
3636                final int procUid = procs.keyAt(i);
3637                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3638                    // Don't use an app process or different user process for system component.
3639                    continue;
3640                }
3641                return procs.valueAt(i);
3642            }
3643        }
3644        ProcessRecord proc = mProcessNames.get(processName, uid);
3645        if (false && proc != null && !keepIfLarge
3646                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3647                && proc.lastCachedPss >= 4000) {
3648            // Turn this condition on to cause killing to happen regularly, for testing.
3649            if (proc.baseProcessTracker != null) {
3650                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3651            }
3652            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3653        } else if (proc != null && !keepIfLarge
3654                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3655                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3656            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3657            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3658                if (proc.baseProcessTracker != null) {
3659                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3660                }
3661                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3662            }
3663        }
3664        return proc;
3665    }
3666
3667    void notifyPackageUse(String packageName, int reason) {
3668        synchronized(this) {
3669            getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3670        }
3671    }
3672
3673    boolean isNextTransitionForward() {
3674        int transit = mWindowManager.getPendingAppTransition();
3675        return transit == TRANSIT_ACTIVITY_OPEN
3676                || transit == TRANSIT_TASK_OPEN
3677                || transit == TRANSIT_TASK_TO_FRONT;
3678    }
3679
3680    boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3681            String processName, String abiOverride, int uid, Runnable crashHandler) {
3682        synchronized(this) {
3683            ApplicationInfo info = new ApplicationInfo();
3684            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3685            // For isolated processes, the former contains the parent's uid and the latter the
3686            // actual uid of the isolated process.
3687            // In the special case introduced by this method (which is, starting an isolated
3688            // process directly from the SystemServer without an actual parent app process) the
3689            // closest thing to a parent's uid is SYSTEM_UID.
3690            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3691            // the |isolated| logic in the ProcessRecord constructor.
3692            info.uid = SYSTEM_UID;
3693            info.processName = processName;
3694            info.className = entryPoint;
3695            info.packageName = "android";
3696            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3697            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3698                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3699                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3700                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3701                    crashHandler);
3702            return proc != null;
3703        }
3704    }
3705
3706    final ProcessRecord startProcessLocked(String processName,
3707            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3708            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3709            boolean isolated, boolean keepIfLarge) {
3710        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3711                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3712                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3713                null /* crashHandler */);
3714    }
3715
3716    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3717            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3718            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3719            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3720        long startTime = SystemClock.elapsedRealtime();
3721        ProcessRecord app;
3722        if (!isolated) {
3723            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3724            checkTime(startTime, "startProcess: after getProcessRecord");
3725
3726            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3727                // If we are in the background, then check to see if this process
3728                // is bad.  If so, we will just silently fail.
3729                if (mAppErrors.isBadProcessLocked(info)) {
3730                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3731                            + "/" + info.processName);
3732                    return null;
3733                }
3734            } else {
3735                // When the user is explicitly starting a process, then clear its
3736                // crash count so that we won't make it bad until they see at
3737                // least one crash dialog again, and make the process good again
3738                // if it had been bad.
3739                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3740                        + "/" + info.processName);
3741                mAppErrors.resetProcessCrashTimeLocked(info);
3742                if (mAppErrors.isBadProcessLocked(info)) {
3743                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3744                            UserHandle.getUserId(info.uid), info.uid,
3745                            info.processName);
3746                    mAppErrors.clearBadProcessLocked(info);
3747                    if (app != null) {
3748                        app.bad = false;
3749                    }
3750                }
3751            }
3752        } else {
3753            // If this is an isolated process, it can't re-use an existing process.
3754            app = null;
3755        }
3756
3757        // We don't have to do anything more if:
3758        // (1) There is an existing application record; and
3759        // (2) The caller doesn't think it is dead, OR there is no thread
3760        //     object attached to it so we know it couldn't have crashed; and
3761        // (3) There is a pid assigned to it, so it is either starting or
3762        //     already running.
3763        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3764                + " app=" + app + " knownToBeDead=" + knownToBeDead
3765                + " thread=" + (app != null ? app.thread : null)
3766                + " pid=" + (app != null ? app.pid : -1));
3767        if (app != null && app.pid > 0) {
3768            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3769                // We already have the app running, or are waiting for it to
3770                // come up (we have a pid but not yet its thread), so keep it.
3771                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3772                // If this is a new package in the process, add the package to the list
3773                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3774                checkTime(startTime, "startProcess: done, added package to proc");
3775                return app;
3776            }
3777
3778            // An application record is attached to a previous process,
3779            // clean it up now.
3780            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3781            checkTime(startTime, "startProcess: bad proc running, killing");
3782            killProcessGroup(app.uid, app.pid);
3783            handleAppDiedLocked(app, true, true);
3784            checkTime(startTime, "startProcess: done killing old proc");
3785        }
3786
3787        String hostingNameStr = hostingName != null
3788                ? hostingName.flattenToShortString() : null;
3789
3790        if (app == null) {
3791            checkTime(startTime, "startProcess: creating new process record");
3792            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3793            if (app == null) {
3794                Slog.w(TAG, "Failed making new process record for "
3795                        + processName + "/" + info.uid + " isolated=" + isolated);
3796                return null;
3797            }
3798            app.crashHandler = crashHandler;
3799            app.isolatedEntryPoint = entryPoint;
3800            app.isolatedEntryPointArgs = entryPointArgs;
3801            checkTime(startTime, "startProcess: done creating new process record");
3802        } else {
3803            // If this is a new package in the process, add the package to the list
3804            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3805            checkTime(startTime, "startProcess: added package to existing proc");
3806        }
3807
3808        // If the system is not ready yet, then hold off on starting this
3809        // process until it is.
3810        if (!mProcessesReady
3811                && !isAllowedWhileBooting(info)
3812                && !allowWhileBooting) {
3813            if (!mProcessesOnHold.contains(app)) {
3814                mProcessesOnHold.add(app);
3815            }
3816            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3817                    "System not ready, putting on hold: " + app);
3818            checkTime(startTime, "startProcess: returning with proc on hold");
3819            return app;
3820        }
3821
3822        checkTime(startTime, "startProcess: stepping in to startProcess");
3823        final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
3824        checkTime(startTime, "startProcess: done starting proc!");
3825        return success ? app : null;
3826    }
3827
3828    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3829        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3830    }
3831
3832    private final void startProcessLocked(ProcessRecord app,
3833            String hostingType, String hostingNameStr) {
3834        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
3835    }
3836
3837    /**
3838     * @return {@code true} if process start is successful, false otherwise.
3839     */
3840    private final boolean startProcessLocked(ProcessRecord app, String hostingType,
3841            String hostingNameStr, String abiOverride) {
3842        if (app.pendingStart) {
3843            return true;
3844        }
3845        long startTime = SystemClock.elapsedRealtime();
3846        if (app.pid > 0 && app.pid != MY_PID) {
3847            checkTime(startTime, "startProcess: removing from pids map");
3848            synchronized (mPidsSelfLocked) {
3849                mPidsSelfLocked.remove(app.pid);
3850                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3851            }
3852            checkTime(startTime, "startProcess: done removing from pids map");
3853            app.setPid(0);
3854        }
3855
3856        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3857                "startProcessLocked removing on hold: " + app);
3858        mProcessesOnHold.remove(app);
3859
3860        checkTime(startTime, "startProcess: starting to update cpu stats");
3861        updateCpuStats();
3862        checkTime(startTime, "startProcess: done updating cpu stats");
3863
3864        try {
3865            try {
3866                final int userId = UserHandle.getUserId(app.uid);
3867                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3868            } catch (RemoteException e) {
3869                throw e.rethrowAsRuntimeException();
3870            }
3871
3872            int uid = app.uid;
3873            int[] gids = null;
3874            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3875            if (!app.isolated) {
3876                int[] permGids = null;
3877                try {
3878                    checkTime(startTime, "startProcess: getting gids from package manager");
3879                    final IPackageManager pm = AppGlobals.getPackageManager();
3880                    permGids = pm.getPackageGids(app.info.packageName,
3881                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3882                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3883                            StorageManagerInternal.class);
3884                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3885                            app.info.packageName);
3886                } catch (RemoteException e) {
3887                    throw e.rethrowAsRuntimeException();
3888                }
3889
3890                /*
3891                 * Add shared application and profile GIDs so applications can share some
3892                 * resources like shared libraries and access user-wide resources
3893                 */
3894                if (ArrayUtils.isEmpty(permGids)) {
3895                    gids = new int[3];
3896                } else {
3897                    gids = new int[permGids.length + 3];
3898                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3899                }
3900                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3901                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3902                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3903
3904                // Replace any invalid GIDs
3905                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
3906                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
3907            }
3908            checkTime(startTime, "startProcess: building args");
3909            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3910                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3911                        && mTopComponent != null
3912                        && app.processName.equals(mTopComponent.getPackageName())) {
3913                    uid = 0;
3914                }
3915                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3916                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3917                    uid = 0;
3918                }
3919            }
3920            int runtimeFlags = 0;
3921            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3922                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
3923                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3924                // Also turn on CheckJNI for debuggable apps. It's quite
3925                // awkward to turn on otherwise.
3926                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3927            }
3928            // Run the app in safe mode if its manifest requests so or the
3929            // system is booted in safe mode.
3930            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3931                mSafeMode == true) {
3932                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3933            }
3934            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3935                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3936            }
3937            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3938            if ("true".equals(genDebugInfoProperty)) {
3939                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3940            }
3941            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3942                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3943            }
3944            if ("1".equals(SystemProperties.get("debug.assert"))) {
3945                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3946            }
3947            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3948                // Enable all debug flags required by the native debugger.
3949                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3950                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3951                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3952                mNativeDebuggingApp = null;
3953            }
3954
3955            if (app.info.isPrivilegedApp() &&
3956                    SystemProperties.getBoolean("pm.dexopt.priv-apps-oob", false)) {
3957                runtimeFlags |= Zygote.DISABLE_VERIFIER;
3958                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
3959            }
3960
3961            String invokeWith = null;
3962            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3963                // Debuggable apps may include a wrapper script with their library directory.
3964                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3965                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3966                try {
3967                    if (new File(wrapperFileName).exists()) {
3968                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3969                    }
3970                } finally {
3971                    StrictMode.setThreadPolicy(oldPolicy);
3972                }
3973            }
3974
3975            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3976            if (requiredAbi == null) {
3977                requiredAbi = Build.SUPPORTED_ABIS[0];
3978            }
3979
3980            String instructionSet = null;
3981            if (app.info.primaryCpuAbi != null) {
3982                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3983            }
3984
3985            app.gids = gids;
3986            app.requiredAbi = requiredAbi;
3987            app.instructionSet = instructionSet;
3988
3989            // the per-user SELinux context must be set
3990            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3991                Slog.wtf(TAG, "SELinux tag not defined",
3992                        new IllegalStateException("SELinux tag not defined for "
3993                        + app.info.packageName + " (uid " + app.uid + ")"));
3994            }
3995            final String seInfo = app.info.seInfo
3996                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3997            // Start the process.  It will either succeed and return a result containing
3998            // the PID of the new process, or else throw a RuntimeException.
3999            final String entryPoint = "android.app.ActivityThread";
4000
4001            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
4002                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
4003                    startTime);
4004        } catch (RuntimeException e) {
4005            Slog.e(TAG, "Failure starting process " + app.processName, e);
4006
4007            // Something went very wrong while trying to start this process; one
4008            // common case is when the package is frozen due to an active
4009            // upgrade. To recover, clean up any active bookkeeping related to
4010            // starting this process. (We already invoked this method once when
4011            // the package was initially frozen through KILL_APPLICATION_MSG, so
4012            // it doesn't hurt to use it again.)
4013            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4014                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4015            return false;
4016        }
4017    }
4018
4019    @GuardedBy("this")
4020    private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
4021            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4022            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4023            long startTime) {
4024        app.pendingStart = true;
4025        app.killedByAm = false;
4026        app.removed = false;
4027        app.killed = false;
4028        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
4029        app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
4030        if (mConstants.FLAG_PROCESS_START_ASYNC) {
4031            if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
4032                    "Posting procStart msg for " + app.toShortString());
4033            mProcStartHandler.post(() -> {
4034                try {
4035                    synchronized (ActivityManagerService.this) {
4036                        final String reason = isProcStartValidLocked(app, startSeq);
4037                        if (reason != null) {
4038                            Slog.w(TAG_PROCESSES, app + " not valid anymore,"
4039                                    + " don't start process, " + reason);
4040                            app.pendingStart = false;
4041                            return;
4042                        }
4043                        app.usingWrapper = invokeWith != null
4044                                || SystemProperties.get("wrap." + app.processName) != null;
4045                        mPendingStarts.put(startSeq, app);
4046                    }
4047                    final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
4048                            app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
4049                            requiredAbi, instructionSet, invokeWith, app.startTime);
4050                    synchronized (ActivityManagerService.this) {
4051                        handleProcessStartedLocked(app, startResult, startSeq);
4052                    }
4053                } catch (RuntimeException e) {
4054                    synchronized (ActivityManagerService.this) {
4055                        Slog.e(TAG, "Failure starting process " + app.processName, e);
4056                        mPendingStarts.remove(startSeq);
4057                        app.pendingStart = false;
4058                        forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4059                                false, false, true, false, false,
4060                                UserHandle.getUserId(app.userId), "start failure");
4061                    }
4062                }
4063            });
4064            return true;
4065        } else {
4066            try {
4067                final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
4068                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
4069                        invokeWith, startTime);
4070                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
4071                        startSeq, false);
4072            } catch (RuntimeException e) {
4073                Slog.e(TAG, "Failure starting process " + app.processName, e);
4074                app.pendingStart = false;
4075                forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4076                        false, false, true, false, false,
4077                        UserHandle.getUserId(app.userId), "start failure");
4078            }
4079            return app.pid > 0;
4080        }
4081    }
4082
4083    private ProcessStartResult startProcess(String hostingType, String entryPoint,
4084            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4085            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4086            long startTime) {
4087        try {
4088            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
4089                    app.processName);
4090            checkTime(startTime, "startProcess: asking zygote to start proc");
4091            final ProcessStartResult startResult;
4092            if (hostingType.equals("webview_service")) {
4093                startResult = startWebView(entryPoint,
4094                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4095                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4096                        app.info.dataDir, null,
4097                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4098            } else {
4099                startResult = Process.start(entryPoint,
4100                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4101                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4102                        app.info.dataDir, invokeWith,
4103                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4104            }
4105            checkTime(startTime, "startProcess: returned from zygote!");
4106            return startResult;
4107        } finally {
4108            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4109        }
4110    }
4111
4112    @GuardedBy("this")
4113    private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
4114        StringBuilder sb = null;
4115        if (app.killedByAm) {
4116            if (sb == null) sb = new StringBuilder();
4117            sb.append("killedByAm=true;");
4118        }
4119        if (mProcessNames.get(app.processName, app.uid) != app) {
4120            if (sb == null) sb = new StringBuilder();
4121            sb.append("No entry in mProcessNames;");
4122        }
4123        if (!app.pendingStart) {
4124            if (sb == null) sb = new StringBuilder();
4125            sb.append("pendingStart=false;");
4126        }
4127        if (app.startSeq > expectedStartSeq) {
4128            if (sb == null) sb = new StringBuilder();
4129            sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
4130        }
4131        return sb == null ? null : sb.toString();
4132    }
4133
4134    @GuardedBy("this")
4135    private boolean handleProcessStartedLocked(ProcessRecord pending,
4136            ProcessStartResult startResult, long expectedStartSeq) {
4137        // Indicates that this process start has been taken care of.
4138        if (mPendingStarts.get(expectedStartSeq) == null) {
4139            if (pending.pid == startResult.pid) {
4140                pending.usingWrapper = startResult.usingWrapper;
4141                // TODO: Update already existing clients of usingWrapper
4142            }
4143            return false;
4144        }
4145        return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
4146                expectedStartSeq, false);
4147    }
4148
4149    @GuardedBy("this")
4150    private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
4151            long expectedStartSeq, boolean procAttached) {
4152        mPendingStarts.remove(expectedStartSeq);
4153        final String reason = isProcStartValidLocked(app, expectedStartSeq);
4154        if (reason != null) {
4155            Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
4156                    + ", " + reason);
4157            app.pendingStart = false;
4158            Process.killProcessQuiet(pid);
4159            Process.killProcessGroup(app.uid, app.pid);
4160            return false;
4161        }
4162        mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
4163        checkTime(app.startTime, "startProcess: done updating battery stats");
4164
4165        EventLog.writeEvent(EventLogTags.AM_PROC_START,
4166                UserHandle.getUserId(app.startUid), pid, app.startUid,
4167                app.processName, app.hostingType,
4168                app.hostingNameStr != null ? app.hostingNameStr : "");
4169
4170        try {
4171            AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
4172                    app.seInfo, app.info.sourceDir, pid);
4173        } catch (RemoteException ex) {
4174            // Ignore
4175        }
4176
4177        if (app.persistent) {
4178            Watchdog.getInstance().processStarted(app.processName, pid);
4179        }
4180
4181        checkTime(app.startTime, "startProcess: building log message");
4182        StringBuilder buf = mStringBuilder;
4183        buf.setLength(0);
4184        buf.append("Start proc ");
4185        buf.append(pid);
4186        buf.append(':');
4187        buf.append(app.processName);
4188        buf.append('/');
4189        UserHandle.formatUid(buf, app.startUid);
4190        if (app.isolatedEntryPoint != null) {
4191            buf.append(" [");
4192            buf.append(app.isolatedEntryPoint);
4193            buf.append("]");
4194        }
4195        buf.append(" for ");
4196        buf.append(app.hostingType);
4197        if (app.hostingNameStr != null) {
4198            buf.append(" ");
4199            buf.append(app.hostingNameStr);
4200        }
4201        Slog.i(TAG, buf.toString());
4202        app.setPid(pid);
4203        app.usingWrapper = usingWrapper;
4204        app.pendingStart = false;
4205        checkTime(app.startTime, "startProcess: starting to update pids map");
4206        ProcessRecord oldApp;
4207        synchronized (mPidsSelfLocked) {
4208            oldApp = mPidsSelfLocked.get(pid);
4209        }
4210        // If there is already an app occupying that pid that hasn't been cleaned up
4211        if (oldApp != null && !app.isolated) {
4212            // Clean up anything relating to this pid first
4213            Slog.w(TAG, "Reusing pid " + pid
4214                    + " while app is still mapped to it");
4215            cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4216                    true /*replacingPid*/);
4217        }
4218        synchronized (mPidsSelfLocked) {
4219            this.mPidsSelfLocked.put(pid, app);
4220            if (!procAttached) {
4221                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4222                msg.obj = app;
4223                mHandler.sendMessageDelayed(msg, usingWrapper
4224                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4225            }
4226        }
4227        checkTime(app.startTime, "startProcess: done updating pids map");
4228        return true;
4229    }
4230
4231    void updateUsageStats(ActivityRecord component, boolean resumed) {
4232        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4233                "updateUsageStats: comp=" + component + "res=" + resumed);
4234        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4235        StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
4236            component.userId, component.realActivity.getPackageName(),
4237            component.realActivity.getShortClassName(), resumed ? 1 : 0);
4238        if (resumed) {
4239            if (mUsageStatsService != null) {
4240                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4241                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4242
4243            }
4244            synchronized (stats) {
4245                stats.noteActivityResumedLocked(component.app.uid);
4246            }
4247        } else {
4248            if (mUsageStatsService != null) {
4249                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4250                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4251            }
4252            synchronized (stats) {
4253                stats.noteActivityPausedLocked(component.app.uid);
4254            }
4255        }
4256    }
4257
4258    Intent getHomeIntent() {
4259        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4260        intent.setComponent(mTopComponent);
4261        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4262        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4263            intent.addCategory(Intent.CATEGORY_HOME);
4264        }
4265        return intent;
4266    }
4267
4268    boolean startHomeActivityLocked(int userId, String reason) {
4269        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4270                && mTopAction == null) {
4271            // We are running in factory test mode, but unable to find
4272            // the factory test app, so just sit around displaying the
4273            // error message and don't try to start anything.
4274            return false;
4275        }
4276        Intent intent = getHomeIntent();
4277        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4278        if (aInfo != null) {
4279            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4280            // Don't do this if the home app is currently being
4281            // instrumented.
4282            aInfo = new ActivityInfo(aInfo);
4283            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4284            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4285                    aInfo.applicationInfo.uid, true);
4286            if (app == null || app.instr == null) {
4287                intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
4288                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4289                // For ANR debugging to verify if the user activity is the one that actually
4290                // launched.
4291                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4292                mActivityStartController.startHomeActivity(intent, aInfo, myReason);
4293            }
4294        } else {
4295            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4296        }
4297
4298        return true;
4299    }
4300
4301    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4302        ActivityInfo ai = null;
4303        ComponentName comp = intent.getComponent();
4304        try {
4305            if (comp != null) {
4306                // Factory test.
4307                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4308            } else {
4309                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4310                        intent,
4311                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4312                        flags, userId);
4313
4314                if (info != null) {
4315                    ai = info.activityInfo;
4316                }
4317            }
4318        } catch (RemoteException e) {
4319            // ignore
4320        }
4321
4322        return ai;
4323    }
4324
4325    boolean getCheckedForSetup() {
4326        return mCheckedForSetup;
4327    }
4328
4329    void setCheckedForSetup(boolean checked) {
4330        mCheckedForSetup = checked;
4331    }
4332
4333    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4334        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4335    }
4336
4337    void enforceNotIsolatedCaller(String caller) {
4338        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4339            throw new SecurityException("Isolated process not allowed to call " + caller);
4340        }
4341    }
4342
4343    @Override
4344    public int getFrontActivityScreenCompatMode() {
4345        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4346        synchronized (this) {
4347            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4348        }
4349    }
4350
4351    @Override
4352    public void setFrontActivityScreenCompatMode(int mode) {
4353        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4354                "setFrontActivityScreenCompatMode");
4355        synchronized (this) {
4356            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4357        }
4358    }
4359
4360    @Override
4361    public int getPackageScreenCompatMode(String packageName) {
4362        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4363        synchronized (this) {
4364            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4365        }
4366    }
4367
4368    @Override
4369    public void setPackageScreenCompatMode(String packageName, int mode) {
4370        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4371                "setPackageScreenCompatMode");
4372        synchronized (this) {
4373            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4374        }
4375    }
4376
4377    @Override
4378    public boolean getPackageAskScreenCompat(String packageName) {
4379        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4380        synchronized (this) {
4381            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4382        }
4383    }
4384
4385    @Override
4386    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4387        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4388                "setPackageAskScreenCompat");
4389        synchronized (this) {
4390            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4391        }
4392    }
4393
4394    private boolean hasUsageStatsPermission(String callingPackage) {
4395        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4396                Binder.getCallingUid(), callingPackage);
4397        if (mode == AppOpsManager.MODE_DEFAULT) {
4398            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4399                    == PackageManager.PERMISSION_GRANTED;
4400        }
4401        return mode == AppOpsManager.MODE_ALLOWED;
4402    }
4403
4404    @Override
4405    public int getPackageProcessState(String packageName, String callingPackage) {
4406        if (!hasUsageStatsPermission(callingPackage)) {
4407            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4408                    "getPackageProcessState");
4409        }
4410
4411        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4412        synchronized (this) {
4413            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4414                final ProcessRecord proc = mLruProcesses.get(i);
4415                if (procState > proc.setProcState) {
4416                    if (proc.pkgList.containsKey(packageName) ||
4417                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4418                        procState = proc.setProcState;
4419                    }
4420                }
4421            }
4422        }
4423        return procState;
4424    }
4425
4426    @Override
4427    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4428            throws RemoteException {
4429        synchronized (this) {
4430            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4431            if (app == null) {
4432                throw new IllegalArgumentException("Unknown process: " + process);
4433            }
4434            if (app.thread == null) {
4435                throw new IllegalArgumentException("Process has no app thread");
4436            }
4437            if (app.trimMemoryLevel >= level) {
4438                throw new IllegalArgumentException(
4439                        "Unable to set a higher trim level than current level");
4440            }
4441            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4442                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4443                throw new IllegalArgumentException("Unable to set a background trim level "
4444                    + "on a foreground process");
4445            }
4446            app.thread.scheduleTrimMemory(level);
4447            app.trimMemoryLevel = level;
4448            return true;
4449        }
4450    }
4451
4452    private void dispatchProcessesChanged() {
4453        int N;
4454        synchronized (this) {
4455            N = mPendingProcessChanges.size();
4456            if (mActiveProcessChanges.length < N) {
4457                mActiveProcessChanges = new ProcessChangeItem[N];
4458            }
4459            mPendingProcessChanges.toArray(mActiveProcessChanges);
4460            mPendingProcessChanges.clear();
4461            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4462                    "*** Delivering " + N + " process changes");
4463        }
4464
4465        int i = mProcessObservers.beginBroadcast();
4466        while (i > 0) {
4467            i--;
4468            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4469            if (observer != null) {
4470                try {
4471                    for (int j=0; j<N; j++) {
4472                        ProcessChangeItem item = mActiveProcessChanges[j];
4473                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4474                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4475                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4476                                    + item.uid + ": " + item.foregroundActivities);
4477                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4478                                    item.foregroundActivities);
4479                        }
4480                    }
4481                } catch (RemoteException e) {
4482                }
4483            }
4484        }
4485        mProcessObservers.finishBroadcast();
4486
4487        synchronized (this) {
4488            for (int j=0; j<N; j++) {
4489                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4490            }
4491        }
4492    }
4493
4494    private void dispatchProcessDied(int pid, int uid) {
4495        int i = mProcessObservers.beginBroadcast();
4496        while (i > 0) {
4497            i--;
4498            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4499            if (observer != null) {
4500                try {
4501                    observer.onProcessDied(pid, uid);
4502                } catch (RemoteException e) {
4503                }
4504            }
4505        }
4506        mProcessObservers.finishBroadcast();
4507    }
4508
4509    @VisibleForTesting
4510    void dispatchUidsChanged() {
4511        int N;
4512        synchronized (this) {
4513            N = mPendingUidChanges.size();
4514            if (mActiveUidChanges.length < N) {
4515                mActiveUidChanges = new UidRecord.ChangeItem[N];
4516            }
4517            for (int i=0; i<N; i++) {
4518                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4519                mActiveUidChanges[i] = change;
4520                if (change.uidRecord != null) {
4521                    change.uidRecord.pendingChange = null;
4522                    change.uidRecord = null;
4523                }
4524            }
4525            mPendingUidChanges.clear();
4526            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4527                    "*** Delivering " + N + " uid changes");
4528        }
4529
4530        int i = mUidObservers.beginBroadcast();
4531        while (i > 0) {
4532            i--;
4533            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4534                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4535        }
4536        mUidObservers.finishBroadcast();
4537
4538        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4539            for (int j = 0; j < N; ++j) {
4540                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4541                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4542                    mValidateUids.remove(item.uid);
4543                } else {
4544                    UidRecord validateUid = mValidateUids.get(item.uid);
4545                    if (validateUid == null) {
4546                        validateUid = new UidRecord(item.uid);
4547                        mValidateUids.put(item.uid, validateUid);
4548                    }
4549                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4550                        validateUid.idle = true;
4551                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4552                        validateUid.idle = false;
4553                    }
4554                    validateUid.curProcState = validateUid.setProcState = item.processState;
4555                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4556                }
4557            }
4558        }
4559
4560        synchronized (this) {
4561            for (int j = 0; j < N; j++) {
4562                mAvailUidChanges.add(mActiveUidChanges[j]);
4563            }
4564        }
4565    }
4566
4567    private void dispatchUidsChangedForObserver(IUidObserver observer,
4568            UidObserverRegistration reg, int changesSize) {
4569        if (observer == null) {
4570            return;
4571        }
4572        try {
4573            for (int j = 0; j < changesSize; j++) {
4574                UidRecord.ChangeItem item = mActiveUidChanges[j];
4575                final int change = item.change;
4576                if (change == UidRecord.CHANGE_PROCSTATE &&
4577                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4578                    // No-op common case: no significant change, the observer is not
4579                    // interested in all proc state changes.
4580                    continue;
4581                }
4582                if ((change & UidRecord.CHANGE_IDLE) != 0) {
4583                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4584                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4585                                "UID idle uid=" + item.uid);
4586                        observer.onUidIdle(item.uid, item.ephemeral);
4587                    }
4588                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4589                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4590                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4591                                "UID active uid=" + item.uid);
4592                        observer.onUidActive(item.uid);
4593                    }
4594                }
4595                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4596                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
4597                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4598                                "UID cached uid=" + item.uid);
4599                        observer.onUidCachedChanged(item.uid, true);
4600                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4601                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4602                                "UID active uid=" + item.uid);
4603                        observer.onUidCachedChanged(item.uid, false);
4604                    }
4605                }
4606                if ((change & UidRecord.CHANGE_GONE) != 0) {
4607                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4608                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4609                                "UID gone uid=" + item.uid);
4610                        observer.onUidGone(item.uid, item.ephemeral);
4611                    }
4612                    if (reg.lastProcStates != null) {
4613                        reg.lastProcStates.delete(item.uid);
4614                    }
4615                } else {
4616                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4617                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4618                                "UID CHANGED uid=" + item.uid
4619                                        + ": " + item.processState);
4620                        boolean doReport = true;
4621                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4622                            final int lastState = reg.lastProcStates.get(item.uid,
4623                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4624                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4625                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4626                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4627                                doReport = lastAboveCut != newAboveCut;
4628                            } else {
4629                                doReport = item.processState
4630                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4631                            }
4632                        }
4633                        if (doReport) {
4634                            if (reg.lastProcStates != null) {
4635                                reg.lastProcStates.put(item.uid, item.processState);
4636                            }
4637                            observer.onUidStateChanged(item.uid, item.processState,
4638                                    item.procStateSeq);
4639                        }
4640                    }
4641                }
4642            }
4643        } catch (RemoteException e) {
4644        }
4645    }
4646
4647    void dispatchOomAdjObserver(String msg) {
4648        OomAdjObserver observer;
4649        synchronized (this) {
4650            observer = mCurOomAdjObserver;
4651        }
4652
4653        if (observer != null) {
4654            observer.onOomAdjMessage(msg);
4655        }
4656    }
4657
4658    void setOomAdjObserver(int uid, OomAdjObserver observer) {
4659        synchronized (this) {
4660            mCurOomAdjUid = uid;
4661            mCurOomAdjObserver = observer;
4662        }
4663    }
4664
4665    void clearOomAdjObserver() {
4666        synchronized (this) {
4667            mCurOomAdjUid = -1;
4668            mCurOomAdjObserver = null;
4669        }
4670    }
4671
4672    void reportOomAdjMessageLocked(String tag, String msg) {
4673        Slog.d(tag, msg);
4674        if (mCurOomAdjObserver != null) {
4675            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4676        }
4677    }
4678
4679    @Override
4680    public final int startActivity(IApplicationThread caller, String callingPackage,
4681            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4682            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4683        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4684                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4685                UserHandle.getCallingUserId());
4686    }
4687
4688    @Override
4689    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4690            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4691            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4692        enforceNotIsolatedCaller("startActivity");
4693        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4694                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4695        // TODO: Switch to user app stacks here.
4696        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
4697                .setCaller(caller)
4698                .setCallingPackage(callingPackage)
4699                .setResolvedType(resolvedType)
4700                .setResultTo(resultTo)
4701                .setResultWho(resultWho)
4702                .setRequestCode(requestCode)
4703                .setStartFlags(startFlags)
4704                .setProfilerInfo(profilerInfo)
4705                .setMayWait(bOptions, userId)
4706                .execute();
4707
4708    }
4709
4710    @Override
4711    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4712            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4713            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4714            int userId) {
4715
4716        // This is very dangerous -- it allows you to perform a start activity (including
4717        // permission grants) as any app that may launch one of your own activities.  So
4718        // we will only allow this to be done from activities that are part of the core framework,
4719        // and then only when they are running as the system.
4720        final ActivityRecord sourceRecord;
4721        final int targetUid;
4722        final String targetPackage;
4723        synchronized (this) {
4724            if (resultTo == null) {
4725                throw new SecurityException("Must be called from an activity");
4726            }
4727            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4728            if (sourceRecord == null) {
4729                throw new SecurityException("Called with bad activity token: " + resultTo);
4730            }
4731            if (!sourceRecord.info.packageName.equals("android")) {
4732                throw new SecurityException(
4733                        "Must be called from an activity that is declared in the android package");
4734            }
4735            if (sourceRecord.app == null) {
4736                throw new SecurityException("Called without a process attached to activity");
4737            }
4738            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4739                // This is still okay, as long as this activity is running under the
4740                // uid of the original calling activity.
4741                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4742                    throw new SecurityException(
4743                            "Calling activity in uid " + sourceRecord.app.uid
4744                                    + " must be system uid or original calling uid "
4745                                    + sourceRecord.launchedFromUid);
4746                }
4747            }
4748            if (ignoreTargetSecurity) {
4749                if (intent.getComponent() == null) {
4750                    throw new SecurityException(
4751                            "Component must be specified with ignoreTargetSecurity");
4752                }
4753                if (intent.getSelector() != null) {
4754                    throw new SecurityException(
4755                            "Selector not allowed with ignoreTargetSecurity");
4756                }
4757            }
4758            targetUid = sourceRecord.launchedFromUid;
4759            targetPackage = sourceRecord.launchedFromPackage;
4760        }
4761
4762        if (userId == UserHandle.USER_NULL) {
4763            userId = UserHandle.getUserId(sourceRecord.app.uid);
4764        }
4765
4766        // TODO: Switch to user app stacks here.
4767        try {
4768            return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
4769                    .setCallingUid(targetUid)
4770                    .setCallingPackage(targetPackage)
4771                    .setResolvedType(resolvedType)
4772                    .setResultTo(resultTo)
4773                    .setResultWho(resultWho)
4774                    .setRequestCode(requestCode)
4775                    .setStartFlags(startFlags)
4776                    .setMayWait(bOptions, userId)
4777                    .setIgnoreTargetSecurity(ignoreTargetSecurity)
4778                    .execute();
4779        } catch (SecurityException e) {
4780            // XXX need to figure out how to propagate to original app.
4781            // A SecurityException here is generally actually a fault of the original
4782            // calling activity (such as a fairly granting permissions), so propagate it
4783            // back to them.
4784            /*
4785            StringBuilder msg = new StringBuilder();
4786            msg.append("While launching");
4787            msg.append(intent.toString());
4788            msg.append(": ");
4789            msg.append(e.getMessage());
4790            */
4791            throw e;
4792        }
4793    }
4794
4795    @Override
4796    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4797            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4798            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4799        enforceNotIsolatedCaller("startActivityAndWait");
4800        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4801                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4802        WaitResult res = new WaitResult();
4803        // TODO: Switch to user app stacks here.
4804        mActivityStartController.obtainStarter(intent, "startActivityAndWait")
4805                .setCaller(caller)
4806                .setCallingPackage(callingPackage)
4807                .setResolvedType(resolvedType)
4808                .setResultTo(resultTo)
4809                .setResultWho(resultWho)
4810                .setRequestCode(requestCode)
4811                .setStartFlags(startFlags)
4812                .setMayWait(bOptions, userId)
4813                .setProfilerInfo(profilerInfo)
4814                .setWaitResult(res)
4815                .execute();
4816        return res;
4817    }
4818
4819    @Override
4820    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4821            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4822            int startFlags, Configuration config, Bundle bOptions, int userId) {
4823        enforceNotIsolatedCaller("startActivityWithConfig");
4824        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4825                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4826        // TODO: Switch to user app stacks here.
4827        return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
4828                .setCaller(caller)
4829                .setCallingPackage(callingPackage)
4830                .setResolvedType(resolvedType)
4831                .setResultTo(resultTo)
4832                .setResultWho(resultWho)
4833                .setRequestCode(requestCode)
4834                .setStartFlags(startFlags)
4835                .setGlobalConfiguration(config)
4836                .setMayWait(bOptions, userId)
4837                .execute();
4838    }
4839
4840    @Override
4841    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4842            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4843            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4844            throws TransactionTooLargeException {
4845        enforceNotIsolatedCaller("startActivityIntentSender");
4846        // Refuse possible leaked file descriptors
4847        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4848            throw new IllegalArgumentException("File descriptors passed in Intent");
4849        }
4850
4851        if (!(target instanceof PendingIntentRecord)) {
4852            throw new IllegalArgumentException("Bad PendingIntent object");
4853        }
4854
4855        PendingIntentRecord pir = (PendingIntentRecord)target;
4856
4857        synchronized (this) {
4858            // If this is coming from the currently resumed activity, it is
4859            // effectively saying that app switches are allowed at this point.
4860            final ActivityStack stack = getFocusedStack();
4861            if (stack.mResumedActivity != null &&
4862                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4863                mAppSwitchesAllowedTime = 0;
4864            }
4865        }
4866        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4867                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4868        return ret;
4869    }
4870
4871    @Override
4872    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4873            Intent intent, String resolvedType, IVoiceInteractionSession session,
4874            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4875            Bundle bOptions, int userId) {
4876        enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
4877        if (session == null || interactor == null) {
4878            throw new NullPointerException("null session or interactor");
4879        }
4880        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4881                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4882        // TODO: Switch to user app stacks here.
4883        return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
4884                .setCallingUid(callingUid)
4885                .setCallingPackage(callingPackage)
4886                .setResolvedType(resolvedType)
4887                .setVoiceSession(session)
4888                .setVoiceInteractor(interactor)
4889                .setStartFlags(startFlags)
4890                .setProfilerInfo(profilerInfo)
4891                .setMayWait(bOptions, userId)
4892                .execute();
4893    }
4894
4895    @Override
4896    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4897            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4898        enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
4899        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4900                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4901
4902        return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
4903                .setCallingUid(callingUid)
4904                .setCallingPackage(callingPackage)
4905                .setResolvedType(resolvedType)
4906                .setMayWait(bOptions, userId)
4907                .execute();
4908    }
4909
4910    @Override
4911    public int startRecentsActivity(IAssistDataReceiver assistDataReceiver, Bundle options,
4912            Bundle activityOptions, int userId) {
4913        if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
4914            String msg = "Permission Denial: startRecentsActivity() from pid="
4915                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
4916                    + " not recent tasks package";
4917            Slog.w(TAG, msg);
4918            throw new SecurityException(msg);
4919        }
4920
4921        final int recentsUid = mRecentTasks.getRecentsComponentUid();
4922        final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
4923        final String recentsPackage = recentsComponent.getPackageName();
4924        final long origId = Binder.clearCallingIdentity();
4925        try {
4926            synchronized (this) {
4927                // If provided, kick off the request for the assist data in the background before
4928                // starting the activity
4929                if (assistDataReceiver != null) {
4930                    final AppOpsManager appOpsManager = (AppOpsManager)
4931                            mContext.getSystemService(Context.APP_OPS_SERVICE);
4932                    final AssistDataReceiverProxy proxy = new AssistDataReceiverProxy(
4933                            assistDataReceiver, recentsPackage);
4934                    final AssistDataRequester requester = new AssistDataRequester(mContext, this,
4935                            mWindowManager, appOpsManager, proxy, this,
4936                            OP_ASSIST_STRUCTURE, OP_NONE);
4937                    requester.requestAssistData(mStackSupervisor.getTopVisibleActivities(),
4938                            true /* fetchData */, false /* fetchScreenshots */,
4939                            true /* allowFetchData */, false /* alloweFetchScreenshots */,
4940                            recentsUid, recentsPackage);
4941                }
4942
4943                final Intent intent = new Intent();
4944                intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
4945                intent.setComponent(recentsComponent);
4946                intent.putExtras(options);
4947
4948                return mActivityStartController.obtainStarter(intent, "startRecentsActivity")
4949                        .setCallingUid(recentsUid)
4950                        .setCallingPackage(recentsPackage)
4951                        .setMayWait(activityOptions, userId)
4952                        .execute();
4953            }
4954        } finally {
4955            Binder.restoreCallingIdentity(origId);
4956        }
4957    }
4958
4959    @Override
4960    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4961            throws RemoteException {
4962        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4963        synchronized (this) {
4964            ActivityRecord activity = getFocusedStack().getTopActivity();
4965            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4966                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4967            }
4968            if (mRunningVoice != null || activity.getTask().voiceSession != null
4969                    || activity.voiceSession != null) {
4970                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4971                return;
4972            }
4973            if (activity.pendingVoiceInteractionStart) {
4974                Slog.w(TAG, "Pending start of voice interaction already.");
4975                return;
4976            }
4977            activity.pendingVoiceInteractionStart = true;
4978        }
4979        LocalServices.getService(VoiceInteractionManagerInternal.class)
4980                .startLocalVoiceInteraction(callingActivity, options);
4981    }
4982
4983    @Override
4984    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4985        LocalServices.getService(VoiceInteractionManagerInternal.class)
4986                .stopLocalVoiceInteraction(callingActivity);
4987    }
4988
4989    @Override
4990    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4991        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4992                .supportsLocalVoiceInteraction();
4993    }
4994
4995    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4996            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4997        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4998        if (activityToCallback == null) return;
4999        activityToCallback.setVoiceSessionLocked(voiceSession);
5000
5001        // Inform the activity
5002        try {
5003            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
5004                    voiceInteractor);
5005            long token = Binder.clearCallingIdentity();
5006            try {
5007                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
5008            } finally {
5009                Binder.restoreCallingIdentity(token);
5010            }
5011            // TODO: VI Should we cache the activity so that it's easier to find later
5012            // rather than scan through all the stacks and activities?
5013        } catch (RemoteException re) {
5014            activityToCallback.clearVoiceSessionLocked();
5015            // TODO: VI Should this terminate the voice session?
5016        }
5017    }
5018
5019    @Override
5020    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
5021        synchronized (this) {
5022            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
5023                if (keepAwake) {
5024                    mVoiceWakeLock.acquire();
5025                } else {
5026                    mVoiceWakeLock.release();
5027                }
5028            }
5029        }
5030    }
5031
5032    @Override
5033    public boolean startNextMatchingActivity(IBinder callingActivity,
5034            Intent intent, Bundle bOptions) {
5035        // Refuse possible leaked file descriptors
5036        if (intent != null && intent.hasFileDescriptors() == true) {
5037            throw new IllegalArgumentException("File descriptors passed in Intent");
5038        }
5039        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
5040
5041        synchronized (this) {
5042            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
5043            if (r == null) {
5044                ActivityOptions.abort(options);
5045                return false;
5046            }
5047            if (r.app == null || r.app.thread == null) {
5048                // The caller is not running...  d'oh!
5049                ActivityOptions.abort(options);
5050                return false;
5051            }
5052            intent = new Intent(intent);
5053            // The caller is not allowed to change the data.
5054            intent.setDataAndType(r.intent.getData(), r.intent.getType());
5055            // And we are resetting to find the next component...
5056            intent.setComponent(null);
5057
5058            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5059
5060            ActivityInfo aInfo = null;
5061            try {
5062                List<ResolveInfo> resolves =
5063                    AppGlobals.getPackageManager().queryIntentActivities(
5064                            intent, r.resolvedType,
5065                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
5066                            UserHandle.getCallingUserId()).getList();
5067
5068                // Look for the original activity in the list...
5069                final int N = resolves != null ? resolves.size() : 0;
5070                for (int i=0; i<N; i++) {
5071                    ResolveInfo rInfo = resolves.get(i);
5072                    if (rInfo.activityInfo.packageName.equals(r.packageName)
5073                            && rInfo.activityInfo.name.equals(r.info.name)) {
5074                        // We found the current one...  the next matching is
5075                        // after it.
5076                        i++;
5077                        if (i<N) {
5078                            aInfo = resolves.get(i).activityInfo;
5079                        }
5080                        if (debug) {
5081                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
5082                                    + "/" + r.info.name);
5083                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
5084                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
5085                        }
5086                        break;
5087                    }
5088                }
5089            } catch (RemoteException e) {
5090            }
5091
5092            if (aInfo == null) {
5093                // Nobody who is next!
5094                ActivityOptions.abort(options);
5095                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
5096                return false;
5097            }
5098
5099            intent.setComponent(new ComponentName(
5100                    aInfo.applicationInfo.packageName, aInfo.name));
5101            intent.setFlags(intent.getFlags()&~(
5102                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
5103                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
5104                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
5105                    FLAG_ACTIVITY_NEW_TASK));
5106
5107            // Okay now we need to start the new activity, replacing the
5108            // currently running activity.  This is a little tricky because
5109            // we want to start the new one as if the current one is finished,
5110            // but not finish the current one first so that there is no flicker.
5111            // And thus...
5112            final boolean wasFinishing = r.finishing;
5113            r.finishing = true;
5114
5115            // Propagate reply information over to the new activity.
5116            final ActivityRecord resultTo = r.resultTo;
5117            final String resultWho = r.resultWho;
5118            final int requestCode = r.requestCode;
5119            r.resultTo = null;
5120            if (resultTo != null) {
5121                resultTo.removeResultsLocked(r, resultWho, requestCode);
5122            }
5123
5124            final long origId = Binder.clearCallingIdentity();
5125            // TODO(b/64750076): Check if calling pid should really be -1.
5126            final int res = mActivityStartController
5127                    .obtainStarter(intent, "startNextMatchingActivity")
5128                    .setCaller(r.app.thread)
5129                    .setResolvedType(r.resolvedType)
5130                    .setActivityInfo(aInfo)
5131                    .setResultTo(resultTo != null ? resultTo.appToken : null)
5132                    .setResultWho(resultWho)
5133                    .setRequestCode(requestCode)
5134                    .setCallingPid(-1)
5135                    .setCallingUid(r.launchedFromUid)
5136                    .setCallingPackage(r.launchedFromPackage)
5137                    .setRealCallingPid(-1)
5138                    .setRealCallingUid(r.launchedFromUid)
5139                    .setActivityOptions(options)
5140                    .execute();
5141            Binder.restoreCallingIdentity(origId);
5142
5143            r.finishing = wasFinishing;
5144            if (res != ActivityManager.START_SUCCESS) {
5145                return false;
5146            }
5147            return true;
5148        }
5149    }
5150
5151    @Override
5152    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
5153        enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
5154                "startActivityFromRecents()");
5155
5156        final long origId = Binder.clearCallingIdentity();
5157        try {
5158            synchronized (this) {
5159                return mStackSupervisor.startActivityFromRecents(taskId, bOptions);
5160            }
5161        } finally {
5162            Binder.restoreCallingIdentity(origId);
5163        }
5164    }
5165
5166    @Override
5167    public final int startActivities(IApplicationThread caller, String callingPackage,
5168            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
5169            int userId) {
5170        final String reason = "startActivities";
5171        enforceNotIsolatedCaller(reason);
5172        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5173                userId, false, ALLOW_FULL_ONLY, reason, null);
5174        // TODO: Switch to user app stacks here.
5175        int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
5176                intents, resolvedTypes, resultTo, bOptions, userId, reason);
5177        return ret;
5178    }
5179
5180    @Override
5181    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
5182        synchronized (this) {
5183            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5184            if (r == null) {
5185                return;
5186            }
5187            r.reportFullyDrawnLocked(restoredFromBundle);
5188        }
5189    }
5190
5191    @Override
5192    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
5193        synchronized (this) {
5194            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5195            if (r == null) {
5196                return;
5197            }
5198            final long origId = Binder.clearCallingIdentity();
5199            try {
5200                r.setRequestedOrientation(requestedOrientation);
5201            } finally {
5202                Binder.restoreCallingIdentity(origId);
5203            }
5204        }
5205    }
5206
5207    @Override
5208    public int getRequestedOrientation(IBinder token) {
5209        synchronized (this) {
5210            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5211            if (r == null) {
5212                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5213            }
5214            return r.getRequestedOrientation();
5215        }
5216    }
5217
5218    @Override
5219    public final void requestActivityRelaunch(IBinder token) {
5220        synchronized(this) {
5221            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5222            if (r == null) {
5223                return;
5224            }
5225            final long origId = Binder.clearCallingIdentity();
5226            try {
5227                r.forceNewConfig = true;
5228                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5229                        true /* preserveWindow */);
5230            } finally {
5231                Binder.restoreCallingIdentity(origId);
5232            }
5233        }
5234    }
5235
5236    /**
5237     * This is the internal entry point for handling Activity.finish().
5238     *
5239     * @param token The Binder token referencing the Activity we want to finish.
5240     * @param resultCode Result code, if any, from this Activity.
5241     * @param resultData Result data (Intent), if any, from this Activity.
5242     * @param finishTask Whether to finish the task associated with this Activity.
5243     *
5244     * @return Returns true if the activity successfully finished, or false if it is still running.
5245     */
5246    @Override
5247    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5248            int finishTask) {
5249        // Refuse possible leaked file descriptors
5250        if (resultData != null && resultData.hasFileDescriptors() == true) {
5251            throw new IllegalArgumentException("File descriptors passed in Intent");
5252        }
5253
5254        synchronized(this) {
5255            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5256            if (r == null) {
5257                return true;
5258            }
5259            // Keep track of the root activity of the task before we finish it
5260            TaskRecord tr = r.getTask();
5261            ActivityRecord rootR = tr.getRootActivity();
5262            if (rootR == null) {
5263                Slog.w(TAG, "Finishing task with all activities already finished");
5264            }
5265            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5266            // finish.
5267            if (mLockTaskController.activityBlockedFromFinish(r)) {
5268                return false;
5269            }
5270
5271            if (mController != null) {
5272                // Find the first activity that is not finishing.
5273                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5274                if (next != null) {
5275                    // ask watcher if this is allowed
5276                    boolean resumeOK = true;
5277                    try {
5278                        resumeOK = mController.activityResuming(next.packageName);
5279                    } catch (RemoteException e) {
5280                        mController = null;
5281                        Watchdog.getInstance().setActivityController(null);
5282                    }
5283
5284                    if (!resumeOK) {
5285                        Slog.i(TAG, "Not finishing activity because controller resumed");
5286                        return false;
5287                    }
5288                }
5289            }
5290            final long origId = Binder.clearCallingIdentity();
5291            try {
5292                boolean res;
5293                final boolean finishWithRootActivity =
5294                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5295                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5296                        || (finishWithRootActivity && r == rootR)) {
5297                    // If requested, remove the task that is associated to this activity only if it
5298                    // was the root activity in the task. The result code and data is ignored
5299                    // because we don't support returning them across task boundaries. Also, to
5300                    // keep backwards compatibility we remove the task from recents when finishing
5301                    // task with root activity.
5302                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5303                            finishWithRootActivity, "finish-activity");
5304                    if (!res) {
5305                        Slog.i(TAG, "Removing task failed to finish activity");
5306                    }
5307                } else {
5308                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5309                            resultData, "app-request", true);
5310                    if (!res) {
5311                        Slog.i(TAG, "Failed to finish by app-request");
5312                    }
5313                }
5314                return res;
5315            } finally {
5316                Binder.restoreCallingIdentity(origId);
5317            }
5318        }
5319    }
5320
5321    @Override
5322    public final void finishHeavyWeightApp() {
5323        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5324                != PackageManager.PERMISSION_GRANTED) {
5325            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5326                    + Binder.getCallingPid()
5327                    + ", uid=" + Binder.getCallingUid()
5328                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5329            Slog.w(TAG, msg);
5330            throw new SecurityException(msg);
5331        }
5332
5333        synchronized(this) {
5334            final ProcessRecord proc = mHeavyWeightProcess;
5335            if (proc == null) {
5336                return;
5337            }
5338
5339            ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
5340            for (int i = 0; i < activities.size(); i++) {
5341                ActivityRecord r = activities.get(i);
5342                if (!r.finishing && r.isInStackLocked()) {
5343                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5344                            null, "finish-heavy", true);
5345                }
5346            }
5347
5348            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5349                    proc.userId, 0));
5350            mHeavyWeightProcess = null;
5351        }
5352    }
5353
5354    @Override
5355    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5356            String message) {
5357        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5358                != PackageManager.PERMISSION_GRANTED) {
5359            String msg = "Permission Denial: crashApplication() from pid="
5360                    + Binder.getCallingPid()
5361                    + ", uid=" + Binder.getCallingUid()
5362                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5363            Slog.w(TAG, msg);
5364            throw new SecurityException(msg);
5365        }
5366
5367        synchronized(this) {
5368            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5369        }
5370    }
5371
5372    @Override
5373    public final void finishSubActivity(IBinder token, String resultWho,
5374            int requestCode) {
5375        synchronized(this) {
5376            final long origId = Binder.clearCallingIdentity();
5377            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5378            if (r != null) {
5379                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5380            }
5381            Binder.restoreCallingIdentity(origId);
5382        }
5383    }
5384
5385    @Override
5386    public boolean finishActivityAffinity(IBinder token) {
5387        synchronized(this) {
5388            final long origId = Binder.clearCallingIdentity();
5389            try {
5390                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5391                if (r == null) {
5392                    return false;
5393                }
5394
5395                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5396                // can finish.
5397                final TaskRecord task = r.getTask();
5398                if (mLockTaskController.activityBlockedFromFinish(r)) {
5399                    return false;
5400                }
5401                return task.getStack().finishActivityAffinityLocked(r);
5402            } finally {
5403                Binder.restoreCallingIdentity(origId);
5404            }
5405        }
5406    }
5407
5408    @Override
5409    public void finishVoiceTask(IVoiceInteractionSession session) {
5410        synchronized (this) {
5411            final long origId = Binder.clearCallingIdentity();
5412            try {
5413                // TODO: VI Consider treating local voice interactions and voice tasks
5414                // differently here
5415                mStackSupervisor.finishVoiceTask(session);
5416            } finally {
5417                Binder.restoreCallingIdentity(origId);
5418            }
5419        }
5420
5421    }
5422
5423    @Override
5424    public boolean releaseActivityInstance(IBinder token) {
5425        synchronized(this) {
5426            final long origId = Binder.clearCallingIdentity();
5427            try {
5428                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5429                if (r == null) {
5430                    return false;
5431                }
5432                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5433            } finally {
5434                Binder.restoreCallingIdentity(origId);
5435            }
5436        }
5437    }
5438
5439    @Override
5440    public void releaseSomeActivities(IApplicationThread appInt) {
5441        synchronized(this) {
5442            final long origId = Binder.clearCallingIdentity();
5443            try {
5444                ProcessRecord app = getRecordForAppLocked(appInt);
5445                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5446            } finally {
5447                Binder.restoreCallingIdentity(origId);
5448            }
5449        }
5450    }
5451
5452    @Override
5453    public boolean willActivityBeVisible(IBinder token) {
5454        synchronized(this) {
5455            ActivityStack stack = ActivityRecord.getStackLocked(token);
5456            if (stack != null) {
5457                return stack.willActivityBeVisibleLocked(token);
5458            }
5459            return false;
5460        }
5461    }
5462
5463    @Override
5464    public void overridePendingTransition(IBinder token, String packageName,
5465            int enterAnim, int exitAnim) {
5466        synchronized(this) {
5467            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5468            if (self == null) {
5469                return;
5470            }
5471
5472            final long origId = Binder.clearCallingIdentity();
5473
5474            if (self.state == ActivityState.RESUMED
5475                    || self.state == ActivityState.PAUSING) {
5476                mWindowManager.overridePendingAppTransition(packageName,
5477                        enterAnim, exitAnim, null);
5478            }
5479
5480            Binder.restoreCallingIdentity(origId);
5481        }
5482    }
5483
5484    /**
5485     * Main function for removing an existing process from the activity manager
5486     * as a result of that process going away.  Clears out all connections
5487     * to the process.
5488     */
5489    private final void handleAppDiedLocked(ProcessRecord app,
5490            boolean restarting, boolean allowRestart) {
5491        int pid = app.pid;
5492        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5493                false /*replacingPid*/);
5494        if (!kept && !restarting) {
5495            removeLruProcessLocked(app);
5496            if (pid > 0) {
5497                ProcessList.remove(pid);
5498            }
5499        }
5500
5501        if (mProfileProc == app) {
5502            clearProfilerLocked();
5503        }
5504
5505        // Remove this application's activities from active lists.
5506        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5507
5508        app.clearRecentTasks();
5509
5510        app.activities.clear();
5511
5512        if (app.instr != null) {
5513            Slog.w(TAG, "Crash of app " + app.processName
5514                  + " running instrumentation " + app.instr.mClass);
5515            Bundle info = new Bundle();
5516            info.putString("shortMsg", "Process crashed.");
5517            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5518        }
5519
5520        mWindowManager.deferSurfaceLayout();
5521        try {
5522            if (!restarting && hasVisibleActivities
5523                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5524                // If there was nothing to resume, and we are not already restarting this process, but
5525                // there is a visible activity that is hosted by the process...  then make sure all
5526                // visible activities are running, taking care of restarting this process.
5527                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5528            }
5529        } finally {
5530            mWindowManager.continueSurfaceLayout();
5531        }
5532    }
5533
5534    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5535        final IBinder threadBinder = thread.asBinder();
5536        // Find the application record.
5537        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5538            final ProcessRecord rec = mLruProcesses.get(i);
5539            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5540                return i;
5541            }
5542        }
5543        return -1;
5544    }
5545
5546    ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
5547        if (thread == null) {
5548            return null;
5549        }
5550
5551        int appIndex = getLRURecordIndexForAppLocked(thread);
5552        if (appIndex >= 0) {
5553            return mLruProcesses.get(appIndex);
5554        }
5555
5556        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5557        // double-check that.
5558        final IBinder threadBinder = thread.asBinder();
5559        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5560        for (int i = pmap.size()-1; i >= 0; i--) {
5561            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5562            for (int j = procs.size()-1; j >= 0; j--) {
5563                final ProcessRecord proc = procs.valueAt(j);
5564                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5565                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5566                            + proc);
5567                    return proc;
5568                }
5569            }
5570        }
5571
5572        return null;
5573    }
5574
5575    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5576        // If there are no longer any background processes running,
5577        // and the app that died was not running instrumentation,
5578        // then tell everyone we are now low on memory.
5579        boolean haveBg = false;
5580        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5581            ProcessRecord rec = mLruProcesses.get(i);
5582            if (rec.thread != null
5583                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5584                haveBg = true;
5585                break;
5586            }
5587        }
5588
5589        if (!haveBg) {
5590            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5591            if (doReport) {
5592                long now = SystemClock.uptimeMillis();
5593                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5594                    doReport = false;
5595                } else {
5596                    mLastMemUsageReportTime = now;
5597                }
5598            }
5599            final ArrayList<ProcessMemInfo> memInfos
5600                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5601            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5602            long now = SystemClock.uptimeMillis();
5603            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5604                ProcessRecord rec = mLruProcesses.get(i);
5605                if (rec == dyingProc || rec.thread == null) {
5606                    continue;
5607                }
5608                if (doReport) {
5609                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5610                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5611                }
5612                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5613                    // The low memory report is overriding any current
5614                    // state for a GC request.  Make sure to do
5615                    // heavy/important/visible/foreground processes first.
5616                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5617                        rec.lastRequestedGc = 0;
5618                    } else {
5619                        rec.lastRequestedGc = rec.lastLowMemory;
5620                    }
5621                    rec.reportLowMemory = true;
5622                    rec.lastLowMemory = now;
5623                    mProcessesToGc.remove(rec);
5624                    addProcessToGcListLocked(rec);
5625                }
5626            }
5627            if (doReport) {
5628                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5629                mHandler.sendMessage(msg);
5630            }
5631            scheduleAppGcsLocked();
5632        }
5633    }
5634
5635    final void appDiedLocked(ProcessRecord app) {
5636       appDiedLocked(app, app.pid, app.thread, false);
5637    }
5638
5639    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5640            boolean fromBinderDied) {
5641        // First check if this ProcessRecord is actually active for the pid.
5642        synchronized (mPidsSelfLocked) {
5643            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5644            if (curProc != app) {
5645                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5646                return;
5647            }
5648        }
5649
5650        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5651        synchronized (stats) {
5652            stats.noteProcessDiedLocked(app.info.uid, pid);
5653        }
5654
5655        if (!app.killed) {
5656            if (!fromBinderDied) {
5657                killProcessQuiet(pid);
5658            }
5659            killProcessGroup(app.uid, pid);
5660            app.killed = true;
5661        }
5662
5663        // Clean up already done if the process has been re-started.
5664        if (app.pid == pid && app.thread != null &&
5665                app.thread.asBinder() == thread.asBinder()) {
5666            boolean doLowMem = app.instr == null;
5667            boolean doOomAdj = doLowMem;
5668            if (!app.killedByAm) {
5669                Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5670                        + ProcessList.makeOomAdjString(app.setAdj)
5671                        + ProcessList.makeProcStateString(app.setProcState));
5672                mAllowLowerMemLevel = true;
5673            } else {
5674                // Note that we always want to do oom adj to update our state with the
5675                // new number of procs.
5676                mAllowLowerMemLevel = false;
5677                doLowMem = false;
5678            }
5679            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5680                    app.setAdj, app.setProcState);
5681            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5682                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5683            handleAppDiedLocked(app, false, true);
5684
5685            if (doOomAdj) {
5686                updateOomAdjLocked();
5687            }
5688            if (doLowMem) {
5689                doLowMemReportIfNeededLocked(app);
5690            }
5691        } else if (app.pid != pid) {
5692            // A new process has already been started.
5693            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5694                    + ") has died and restarted (pid " + app.pid + ").");
5695            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5696        } else if (DEBUG_PROCESSES) {
5697            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5698                    + thread.asBinder());
5699        }
5700    }
5701
5702    /**
5703     * If a stack trace dump file is configured, dump process stack traces.
5704     * @param clearTraces causes the dump file to be erased prior to the new
5705     *    traces being written, if true; when false, the new traces will be
5706     *    appended to any existing file content.
5707     * @param firstPids of dalvik VM processes to dump stack traces for first
5708     * @param lastPids of dalvik VM processes to dump stack traces for last
5709     * @param nativePids optional list of native pids to dump stack crawls
5710     */
5711    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5712            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5713            ArrayList<Integer> nativePids) {
5714        ArrayList<Integer> extraPids = null;
5715
5716        // Measure CPU usage as soon as we're called in order to get a realistic sampling
5717        // of the top users at the time of the request.
5718        if (processCpuTracker != null) {
5719            processCpuTracker.init();
5720            try {
5721                Thread.sleep(200);
5722            } catch (InterruptedException ignored) {
5723            }
5724
5725            processCpuTracker.update();
5726
5727            // We'll take the stack crawls of just the top apps using CPU.
5728            final int N = processCpuTracker.countWorkingStats();
5729            extraPids = new ArrayList<>();
5730            for (int i = 0; i < N && extraPids.size() < 5; i++) {
5731                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5732                if (lastPids.indexOfKey(stats.pid) >= 0) {
5733                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5734
5735                    extraPids.add(stats.pid);
5736                } else if (DEBUG_ANR) {
5737                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5738                            + stats.pid);
5739                }
5740            }
5741        }
5742
5743        boolean useTombstonedForJavaTraces = false;
5744        File tracesFile;
5745
5746        final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5747        if (tracesDirProp.isEmpty()) {
5748            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5749            // dumping scheme. All traces are written to a global trace file (usually
5750            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5751            // the file if requested.
5752            //
5753            // This mode of operation will be removed in the near future.
5754
5755
5756            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5757            if (globalTracesPath.isEmpty()) {
5758                Slog.w(TAG, "dumpStackTraces: no trace path configured");
5759                return null;
5760            }
5761
5762            tracesFile = new File(globalTracesPath);
5763            try {
5764                if (clearTraces && tracesFile.exists()) {
5765                    tracesFile.delete();
5766                }
5767
5768                tracesFile.createNewFile();
5769                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5770            } catch (IOException e) {
5771                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5772                return null;
5773            }
5774        } else {
5775            File tracesDir = new File(tracesDirProp);
5776            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5777            // Each set of ANR traces is written to a separate file and dumpstate will process
5778            // all such files and add them to a captured bug report if they're recent enough.
5779            maybePruneOldTraces(tracesDir);
5780
5781            // NOTE: We should consider creating the file in native code atomically once we've
5782            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5783            // can be removed.
5784            tracesFile = createAnrDumpFile(tracesDir);
5785            if (tracesFile == null) {
5786                return null;
5787            }
5788
5789            useTombstonedForJavaTraces = true;
5790        }
5791
5792        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5793                useTombstonedForJavaTraces);
5794        return tracesFile;
5795    }
5796
5797    @GuardedBy("ActivityManagerService.class")
5798    private static SimpleDateFormat sAnrFileDateFormat;
5799
5800    private static synchronized File createAnrDumpFile(File tracesDir) {
5801        if (sAnrFileDateFormat == null) {
5802            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5803        }
5804
5805        final String formattedDate = sAnrFileDateFormat.format(new Date());
5806        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5807
5808        try {
5809            if (anrFile.createNewFile()) {
5810                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5811                return anrFile;
5812            } else {
5813                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5814            }
5815        } catch (IOException ioe) {
5816            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5817        }
5818
5819        return null;
5820    }
5821
5822    /**
5823     * Prune all trace files that are more than a day old.
5824     *
5825     * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5826     * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5827     * since it's the system_server that creates trace files for most ANRs.
5828     */
5829    private static void maybePruneOldTraces(File tracesDir) {
5830        final long now = System.currentTimeMillis();
5831        final File[] traceFiles = tracesDir.listFiles();
5832
5833        if (traceFiles != null) {
5834            for (File file : traceFiles) {
5835                if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5836                    if (!file.delete()) {
5837                        Slog.w(TAG, "Unable to prune stale trace file: " + file);
5838                    }
5839                }
5840            }
5841        }
5842    }
5843
5844    /**
5845     * Legacy code, do not use. Existing users will be deleted.
5846     *
5847     * @deprecated
5848     */
5849    @Deprecated
5850    public static class DumpStackFileObserver extends FileObserver {
5851        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5852        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5853
5854        private final String mTracesPath;
5855        private boolean mClosed;
5856
5857        public DumpStackFileObserver(String tracesPath) {
5858            super(tracesPath, FileObserver.CLOSE_WRITE);
5859            mTracesPath = tracesPath;
5860        }
5861
5862        @Override
5863        public synchronized void onEvent(int event, String path) {
5864            mClosed = true;
5865            notify();
5866        }
5867
5868        public long dumpWithTimeout(int pid, long timeout) {
5869            sendSignal(pid, SIGNAL_QUIT);
5870            final long start = SystemClock.elapsedRealtime();
5871
5872            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5873            synchronized (this) {
5874                try {
5875                    wait(waitTime); // Wait for traces file to be closed.
5876                } catch (InterruptedException e) {
5877                    Slog.wtf(TAG, e);
5878                }
5879            }
5880
5881            // This avoids a corner case of passing a negative time to the native
5882            // trace in case we've already hit the overall timeout.
5883            final long timeWaited = SystemClock.elapsedRealtime() - start;
5884            if (timeWaited >= timeout) {
5885                return timeWaited;
5886            }
5887
5888            if (!mClosed) {
5889                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5890                       ". Attempting native stack collection.");
5891
5892                final long nativeDumpTimeoutMs = Math.min(
5893                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5894
5895                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5896                        (int) (nativeDumpTimeoutMs / 1000));
5897            }
5898
5899            final long end = SystemClock.elapsedRealtime();
5900            mClosed = false;
5901
5902            return (end - start);
5903        }
5904    }
5905
5906    /**
5907     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5908     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5909     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5910     * attempting to obtain native traces in the case of a failure. Returns the total time spent
5911     * capturing traces.
5912     */
5913    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5914        final long timeStart = SystemClock.elapsedRealtime();
5915        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5916            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5917                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
5918        }
5919
5920        return SystemClock.elapsedRealtime() - timeStart;
5921    }
5922
5923    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5924            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5925            boolean useTombstonedForJavaTraces) {
5926
5927        // We don't need any sort of inotify based monitoring when we're dumping traces via
5928        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5929        // control of all writes to the file in question.
5930        final DumpStackFileObserver observer;
5931        if (useTombstonedForJavaTraces) {
5932            observer = null;
5933        } else {
5934            // Use a FileObserver to detect when traces finish writing.
5935            // The order of traces is considered important to maintain for legibility.
5936            observer = new DumpStackFileObserver(tracesFile);
5937        }
5938
5939        // We must complete all stack dumps within 20 seconds.
5940        long remainingTime = 20 * 1000;
5941        try {
5942            if (observer != null) {
5943                observer.startWatching();
5944            }
5945
5946            // First collect all of the stacks of the most important pids.
5947            if (firstPids != null) {
5948                int num = firstPids.size();
5949                for (int i = 0; i < num; i++) {
5950                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5951                            + firstPids.get(i));
5952                    final long timeTaken;
5953                    if (useTombstonedForJavaTraces) {
5954                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5955                    } else {
5956                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5957                    }
5958
5959                    remainingTime -= timeTaken;
5960                    if (remainingTime <= 0) {
5961                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5962                            "); deadline exceeded.");
5963                        return;
5964                    }
5965
5966                    if (DEBUG_ANR) {
5967                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5968                    }
5969                }
5970            }
5971
5972            // Next collect the stacks of the native pids
5973            if (nativePids != null) {
5974                for (int pid : nativePids) {
5975                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5976                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5977
5978                    final long start = SystemClock.elapsedRealtime();
5979                    Debug.dumpNativeBacktraceToFileTimeout(
5980                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5981                    final long timeTaken = SystemClock.elapsedRealtime() - start;
5982
5983                    remainingTime -= timeTaken;
5984                    if (remainingTime <= 0) {
5985                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5986                            "); deadline exceeded.");
5987                        return;
5988                    }
5989
5990                    if (DEBUG_ANR) {
5991                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5992                    }
5993                }
5994            }
5995
5996            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5997            if (extraPids != null) {
5998                for (int pid : extraPids) {
5999                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
6000
6001                    final long timeTaken;
6002                    if (useTombstonedForJavaTraces) {
6003                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
6004                    } else {
6005                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
6006                    }
6007
6008                    remainingTime -= timeTaken;
6009                    if (remainingTime <= 0) {
6010                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
6011                                "); deadline exceeded.");
6012                        return;
6013                    }
6014
6015                    if (DEBUG_ANR) {
6016                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
6017                    }
6018                }
6019            }
6020        } finally {
6021            if (observer != null) {
6022                observer.stopWatching();
6023            }
6024        }
6025    }
6026
6027    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
6028        if (true || Build.IS_USER) {
6029            return;
6030        }
6031        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6032        if (tracesPath == null || tracesPath.length() == 0) {
6033            return;
6034        }
6035
6036        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
6037        StrictMode.allowThreadDiskWrites();
6038        try {
6039            final File tracesFile = new File(tracesPath);
6040            final File tracesDir = tracesFile.getParentFile();
6041            final File tracesTmp = new File(tracesDir, "__tmp__");
6042            try {
6043                if (tracesFile.exists()) {
6044                    tracesTmp.delete();
6045                    tracesFile.renameTo(tracesTmp);
6046                }
6047                StringBuilder sb = new StringBuilder();
6048                Time tobj = new Time();
6049                tobj.set(System.currentTimeMillis());
6050                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
6051                sb.append(": ");
6052                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
6053                sb.append(" since ");
6054                sb.append(msg);
6055                FileOutputStream fos = new FileOutputStream(tracesFile);
6056                fos.write(sb.toString().getBytes());
6057                if (app == null) {
6058                    fos.write("\n*** No application process!".getBytes());
6059                }
6060                fos.close();
6061                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
6062            } catch (IOException e) {
6063                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
6064                return;
6065            }
6066
6067            if (app != null && app.pid > 0) {
6068                ArrayList<Integer> firstPids = new ArrayList<Integer>();
6069                firstPids.add(app.pid);
6070                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
6071            }
6072
6073            File lastTracesFile = null;
6074            File curTracesFile = null;
6075            for (int i=9; i>=0; i--) {
6076                String name = String.format(Locale.US, "slow%02d.txt", i);
6077                curTracesFile = new File(tracesDir, name);
6078                if (curTracesFile.exists()) {
6079                    if (lastTracesFile != null) {
6080                        curTracesFile.renameTo(lastTracesFile);
6081                    } else {
6082                        curTracesFile.delete();
6083                    }
6084                }
6085                lastTracesFile = curTracesFile;
6086            }
6087            tracesFile.renameTo(curTracesFile);
6088            if (tracesTmp.exists()) {
6089                tracesTmp.renameTo(tracesFile);
6090            }
6091        } finally {
6092            StrictMode.setThreadPolicy(oldPolicy);
6093        }
6094    }
6095
6096    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
6097        if (!mLaunchWarningShown) {
6098            mLaunchWarningShown = true;
6099            mUiHandler.post(new Runnable() {
6100                @Override
6101                public void run() {
6102                    synchronized (ActivityManagerService.this) {
6103                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
6104                        d.show();
6105                        mUiHandler.postDelayed(new Runnable() {
6106                            @Override
6107                            public void run() {
6108                                synchronized (ActivityManagerService.this) {
6109                                    d.dismiss();
6110                                    mLaunchWarningShown = false;
6111                                }
6112                            }
6113                        }, 4000);
6114                    }
6115                }
6116            });
6117        }
6118    }
6119
6120    @Override
6121    public boolean clearApplicationUserData(final String packageName, boolean keepState,
6122            final IPackageDataObserver observer, int userId) {
6123        enforceNotIsolatedCaller("clearApplicationUserData");
6124        int uid = Binder.getCallingUid();
6125        int pid = Binder.getCallingPid();
6126        final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
6127                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
6128
6129        final ApplicationInfo appInfo;
6130        final boolean isInstantApp;
6131
6132        long callingId = Binder.clearCallingIdentity();
6133        try {
6134            IPackageManager pm = AppGlobals.getPackageManager();
6135            synchronized(this) {
6136                // Instant packages are not protected
6137                if (getPackageManagerInternalLocked().isPackageDataProtected(
6138                        resolvedUserId, packageName)) {
6139                    throw new SecurityException(
6140                            "Cannot clear data for a protected package: " + packageName);
6141                }
6142
6143                ApplicationInfo applicationInfo = null;
6144                try {
6145                    applicationInfo = pm.getApplicationInfo(packageName,
6146                            MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
6147                } catch (RemoteException e) {
6148                    /* ignore */
6149                }
6150                appInfo = applicationInfo;
6151
6152                final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
6153
6154                if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
6155                        pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
6156                    throw new SecurityException("PID " + pid + " does not have permission "
6157                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
6158                            + " of package " + packageName);
6159                }
6160
6161                final boolean hasInstantMetadata = getPackageManagerInternalLocked()
6162                        .hasInstantApplicationMetadata(packageName, resolvedUserId);
6163                final boolean isUninstalledAppWithoutInstantMetadata =
6164                        (appInfo == null && !hasInstantMetadata);
6165                isInstantApp = (appInfo != null && appInfo.isInstantApp())
6166                        || hasInstantMetadata;
6167                final boolean canAccessInstantApps = checkComponentPermission(
6168                        permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
6169                        == PackageManager.PERMISSION_GRANTED;
6170
6171                if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
6172                        && !canAccessInstantApps)) {
6173                    Slog.w(TAG, "Invalid packageName: " + packageName);
6174                    if (observer != null) {
6175                        try {
6176                            observer.onRemoveCompleted(packageName, false);
6177                        } catch (RemoteException e) {
6178                            Slog.i(TAG, "Observer no longer exists.");
6179                        }
6180                    }
6181                    return false;
6182                }
6183
6184                if (appInfo != null) {
6185                    forceStopPackageLocked(packageName, appInfo.uid, "clear data");
6186                    mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
6187                }
6188            }
6189
6190            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
6191                @Override
6192                public void onRemoveCompleted(String packageName, boolean succeeded)
6193                        throws RemoteException {
6194                    if (appInfo != null) {
6195                        synchronized (ActivityManagerService.this) {
6196                            finishForceStopPackageLocked(packageName, appInfo.uid);
6197                        }
6198                    }
6199                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
6200                            Uri.fromParts("package", packageName, null));
6201                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6202                    intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6203                    intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6204                    if (isInstantApp) {
6205                        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6206                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6207                                null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6208                                resolvedUserId);
6209                    } else {
6210                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6211                                null, null, null, null, false, false, resolvedUserId);
6212                    }
6213
6214                    if (observer != null) {
6215                        observer.onRemoveCompleted(packageName, succeeded);
6216                    }
6217                }
6218            };
6219
6220            try {
6221                // Clear application user data
6222                pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6223
6224                if (appInfo != null) {
6225                    // Restore already established notification state and permission grants,
6226                    // so it told us to keep those intact -- it's about to emplace app data
6227                    // that is appropriate for those bits of system state.
6228                    if (!keepState) {
6229                        synchronized (this) {
6230                            // Remove all permissions granted from/to this package
6231                            removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6232                        }
6233
6234                        // Reset notification state
6235                        INotificationManager inm = NotificationManager.getService();
6236                        inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6237                    }
6238
6239                    // Clear its scheduled jobs
6240                    JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
6241                    js.cancelJobsForUid(appInfo.uid, "clear data");
6242
6243                    // Clear its pending alarms
6244                    AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
6245                    ami.removeAlarmsForUid(uid);
6246                }
6247            } catch (RemoteException e) {
6248            }
6249        } finally {
6250            Binder.restoreCallingIdentity(callingId);
6251        }
6252        return true;
6253    }
6254
6255    @Override
6256    public void killBackgroundProcesses(final String packageName, int userId) {
6257        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6258                != PackageManager.PERMISSION_GRANTED &&
6259                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6260                        != PackageManager.PERMISSION_GRANTED) {
6261            String msg = "Permission Denial: killBackgroundProcesses() from pid="
6262                    + Binder.getCallingPid()
6263                    + ", uid=" + Binder.getCallingUid()
6264                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6265            Slog.w(TAG, msg);
6266            throw new SecurityException(msg);
6267        }
6268
6269        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6270                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6271        long callingId = Binder.clearCallingIdentity();
6272        try {
6273            IPackageManager pm = AppGlobals.getPackageManager();
6274            synchronized(this) {
6275                int appId = -1;
6276                try {
6277                    appId = UserHandle.getAppId(
6278                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6279                } catch (RemoteException e) {
6280                }
6281                if (appId == -1) {
6282                    Slog.w(TAG, "Invalid packageName: " + packageName);
6283                    return;
6284                }
6285                killPackageProcessesLocked(packageName, appId, userId,
6286                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6287            }
6288        } finally {
6289            Binder.restoreCallingIdentity(callingId);
6290        }
6291    }
6292
6293    @Override
6294    public void killAllBackgroundProcesses() {
6295        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6296                != PackageManager.PERMISSION_GRANTED) {
6297            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6298                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6299                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6300            Slog.w(TAG, msg);
6301            throw new SecurityException(msg);
6302        }
6303
6304        final long callingId = Binder.clearCallingIdentity();
6305        try {
6306            synchronized (this) {
6307                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6308                final int NP = mProcessNames.getMap().size();
6309                for (int ip = 0; ip < NP; ip++) {
6310                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6311                    final int NA = apps.size();
6312                    for (int ia = 0; ia < NA; ia++) {
6313                        final ProcessRecord app = apps.valueAt(ia);
6314                        if (app.persistent) {
6315                            // We don't kill persistent processes.
6316                            continue;
6317                        }
6318                        if (app.removed) {
6319                            procs.add(app);
6320                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6321                            app.removed = true;
6322                            procs.add(app);
6323                        }
6324                    }
6325                }
6326
6327                final int N = procs.size();
6328                for (int i = 0; i < N; i++) {
6329                    removeProcessLocked(procs.get(i), false, true, "kill all background");
6330                }
6331
6332                mAllowLowerMemLevel = true;
6333
6334                updateOomAdjLocked();
6335                doLowMemReportIfNeededLocked(null);
6336            }
6337        } finally {
6338            Binder.restoreCallingIdentity(callingId);
6339        }
6340    }
6341
6342    /**
6343     * Kills all background processes, except those matching any of the
6344     * specified properties.
6345     *
6346     * @param minTargetSdk the target SDK version at or above which to preserve
6347     *                     processes, or {@code -1} to ignore the target SDK
6348     * @param maxProcState the process state at or below which to preserve
6349     *                     processes, or {@code -1} to ignore the process state
6350     */
6351    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6352        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6353                != PackageManager.PERMISSION_GRANTED) {
6354            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6355                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6356                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6357            Slog.w(TAG, msg);
6358            throw new SecurityException(msg);
6359        }
6360
6361        final long callingId = Binder.clearCallingIdentity();
6362        try {
6363            synchronized (this) {
6364                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6365                final int NP = mProcessNames.getMap().size();
6366                for (int ip = 0; ip < NP; ip++) {
6367                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6368                    final int NA = apps.size();
6369                    for (int ia = 0; ia < NA; ia++) {
6370                        final ProcessRecord app = apps.valueAt(ia);
6371                        if (app.removed) {
6372                            procs.add(app);
6373                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6374                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6375                            app.removed = true;
6376                            procs.add(app);
6377                        }
6378                    }
6379                }
6380
6381                final int N = procs.size();
6382                for (int i = 0; i < N; i++) {
6383                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6384                }
6385            }
6386        } finally {
6387            Binder.restoreCallingIdentity(callingId);
6388        }
6389    }
6390
6391    @Override
6392    public void forceStopPackage(final String packageName, int userId) {
6393        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6394                != PackageManager.PERMISSION_GRANTED) {
6395            String msg = "Permission Denial: forceStopPackage() from pid="
6396                    + Binder.getCallingPid()
6397                    + ", uid=" + Binder.getCallingUid()
6398                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6399            Slog.w(TAG, msg);
6400            throw new SecurityException(msg);
6401        }
6402        final int callingPid = Binder.getCallingPid();
6403        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6404                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6405        long callingId = Binder.clearCallingIdentity();
6406        try {
6407            IPackageManager pm = AppGlobals.getPackageManager();
6408            synchronized(this) {
6409                int[] users = userId == UserHandle.USER_ALL
6410                        ? mUserController.getUsers() : new int[] { userId };
6411                for (int user : users) {
6412                    int pkgUid = -1;
6413                    try {
6414                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6415                                user);
6416                    } catch (RemoteException e) {
6417                    }
6418                    if (pkgUid == -1) {
6419                        Slog.w(TAG, "Invalid packageName: " + packageName);
6420                        continue;
6421                    }
6422                    try {
6423                        pm.setPackageStoppedState(packageName, true, user);
6424                    } catch (RemoteException e) {
6425                    } catch (IllegalArgumentException e) {
6426                        Slog.w(TAG, "Failed trying to unstop package "
6427                                + packageName + ": " + e);
6428                    }
6429                    if (mUserController.isUserRunning(user, 0)) {
6430                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6431                        finishForceStopPackageLocked(packageName, pkgUid);
6432                    }
6433                }
6434            }
6435        } finally {
6436            Binder.restoreCallingIdentity(callingId);
6437        }
6438    }
6439
6440    @Override
6441    public void addPackageDependency(String packageName) {
6442        synchronized (this) {
6443            int callingPid = Binder.getCallingPid();
6444            if (callingPid == myPid()) {
6445                //  Yeah, um, no.
6446                return;
6447            }
6448            ProcessRecord proc;
6449            synchronized (mPidsSelfLocked) {
6450                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6451            }
6452            if (proc != null) {
6453                if (proc.pkgDeps == null) {
6454                    proc.pkgDeps = new ArraySet<String>(1);
6455                }
6456                proc.pkgDeps.add(packageName);
6457            }
6458        }
6459    }
6460
6461    /*
6462     * The pkg name and app id have to be specified.
6463     */
6464    @Override
6465    public void killApplication(String pkg, int appId, int userId, String reason) {
6466        if (pkg == null) {
6467            return;
6468        }
6469        // Make sure the uid is valid.
6470        if (appId < 0) {
6471            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6472            return;
6473        }
6474        int callerUid = Binder.getCallingUid();
6475        // Only the system server can kill an application
6476        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6477            // Post an aysnc message to kill the application
6478            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6479            msg.arg1 = appId;
6480            msg.arg2 = userId;
6481            Bundle bundle = new Bundle();
6482            bundle.putString("pkg", pkg);
6483            bundle.putString("reason", reason);
6484            msg.obj = bundle;
6485            mHandler.sendMessage(msg);
6486        } else {
6487            throw new SecurityException(callerUid + " cannot kill pkg: " +
6488                    pkg);
6489        }
6490    }
6491
6492    @Override
6493    public void closeSystemDialogs(String reason) {
6494        enforceNotIsolatedCaller("closeSystemDialogs");
6495
6496        final int pid = Binder.getCallingPid();
6497        final int uid = Binder.getCallingUid();
6498        final long origId = Binder.clearCallingIdentity();
6499        try {
6500            synchronized (this) {
6501                // Only allow this from foreground processes, so that background
6502                // applications can't abuse it to prevent system UI from being shown.
6503                if (uid >= FIRST_APPLICATION_UID) {
6504                    ProcessRecord proc;
6505                    synchronized (mPidsSelfLocked) {
6506                        proc = mPidsSelfLocked.get(pid);
6507                    }
6508                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6509                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6510                                + " from background process " + proc);
6511                        return;
6512                    }
6513                }
6514                closeSystemDialogsLocked(reason);
6515            }
6516        } finally {
6517            Binder.restoreCallingIdentity(origId);
6518        }
6519    }
6520
6521    void closeSystemDialogsLocked(String reason) {
6522        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6523        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6524                | Intent.FLAG_RECEIVER_FOREGROUND);
6525        if (reason != null) {
6526            intent.putExtra("reason", reason);
6527        }
6528        mWindowManager.closeSystemDialogs(reason);
6529
6530        mStackSupervisor.closeSystemDialogsLocked();
6531
6532        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6533                OP_NONE, null, false, false,
6534                -1, SYSTEM_UID, UserHandle.USER_ALL);
6535    }
6536
6537    @Override
6538    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6539        enforceNotIsolatedCaller("getProcessMemoryInfo");
6540        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6541        for (int i=pids.length-1; i>=0; i--) {
6542            ProcessRecord proc;
6543            int oomAdj;
6544            synchronized (this) {
6545                synchronized (mPidsSelfLocked) {
6546                    proc = mPidsSelfLocked.get(pids[i]);
6547                    oomAdj = proc != null ? proc.setAdj : 0;
6548                }
6549            }
6550            infos[i] = new Debug.MemoryInfo();
6551            long startTime = SystemClock.currentThreadTimeMillis();
6552            Debug.getMemoryInfo(pids[i], infos[i]);
6553            long endTime = SystemClock.currentThreadTimeMillis();
6554            if (proc != null) {
6555                synchronized (this) {
6556                    if (proc.thread != null && proc.setAdj == oomAdj) {
6557                        // Record this for posterity if the process has been stable.
6558                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6559                                infos[i].getTotalUss(), false,
6560                                ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
6561                                proc.pkgList);
6562                    }
6563                }
6564            }
6565        }
6566        return infos;
6567    }
6568
6569    @Override
6570    public long[] getProcessPss(int[] pids) {
6571        enforceNotIsolatedCaller("getProcessPss");
6572        long[] pss = new long[pids.length];
6573        for (int i=pids.length-1; i>=0; i--) {
6574            ProcessRecord proc;
6575            int oomAdj;
6576            synchronized (this) {
6577                synchronized (mPidsSelfLocked) {
6578                    proc = mPidsSelfLocked.get(pids[i]);
6579                    oomAdj = proc != null ? proc.setAdj : 0;
6580                }
6581            }
6582            long[] tmpUss = new long[1];
6583            long startTime = SystemClock.currentThreadTimeMillis();
6584            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6585            long endTime = SystemClock.currentThreadTimeMillis();
6586            if (proc != null) {
6587                synchronized (this) {
6588                    if (proc.thread != null && proc.setAdj == oomAdj) {
6589                        // Record this for posterity if the process has been stable.
6590                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false,
6591                                ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
6592                    }
6593                }
6594            }
6595        }
6596        return pss;
6597    }
6598
6599    @Override
6600    public void killApplicationProcess(String processName, int uid) {
6601        if (processName == null) {
6602            return;
6603        }
6604
6605        int callerUid = Binder.getCallingUid();
6606        // Only the system server can kill an application
6607        if (callerUid == SYSTEM_UID) {
6608            synchronized (this) {
6609                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6610                if (app != null && app.thread != null) {
6611                    try {
6612                        app.thread.scheduleSuicide();
6613                    } catch (RemoteException e) {
6614                        // If the other end already died, then our work here is done.
6615                    }
6616                } else {
6617                    Slog.w(TAG, "Process/uid not found attempting kill of "
6618                            + processName + " / " + uid);
6619                }
6620            }
6621        } else {
6622            throw new SecurityException(callerUid + " cannot kill app process: " +
6623                    processName);
6624        }
6625    }
6626
6627    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6628        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6629                false, true, false, false, UserHandle.getUserId(uid), reason);
6630    }
6631
6632    private void finishForceStopPackageLocked(final String packageName, int uid) {
6633        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6634                Uri.fromParts("package", packageName, null));
6635        if (!mProcessesReady) {
6636            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6637                    | Intent.FLAG_RECEIVER_FOREGROUND);
6638        }
6639        intent.putExtra(Intent.EXTRA_UID, uid);
6640        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6641        broadcastIntentLocked(null, null, intent,
6642                null, null, 0, null, null, null, OP_NONE,
6643                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6644    }
6645
6646
6647    private final boolean killPackageProcessesLocked(String packageName, int appId,
6648            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6649            boolean doit, boolean evenPersistent, String reason) {
6650        ArrayList<ProcessRecord> procs = new ArrayList<>();
6651
6652        // Remove all processes this package may have touched: all with the
6653        // same UID (except for the system or root user), and all whose name
6654        // matches the package name.
6655        final int NP = mProcessNames.getMap().size();
6656        for (int ip=0; ip<NP; ip++) {
6657            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6658            final int NA = apps.size();
6659            for (int ia=0; ia<NA; ia++) {
6660                ProcessRecord app = apps.valueAt(ia);
6661                if (app.persistent && !evenPersistent) {
6662                    // we don't kill persistent processes
6663                    continue;
6664                }
6665                if (app.removed) {
6666                    if (doit) {
6667                        procs.add(app);
6668                    }
6669                    continue;
6670                }
6671
6672                // Skip process if it doesn't meet our oom adj requirement.
6673                if (app.setAdj < minOomAdj) {
6674                    continue;
6675                }
6676
6677                // If no package is specified, we call all processes under the
6678                // give user id.
6679                if (packageName == null) {
6680                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6681                        continue;
6682                    }
6683                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6684                        continue;
6685                    }
6686                // Package has been specified, we want to hit all processes
6687                // that match it.  We need to qualify this by the processes
6688                // that are running under the specified app and user ID.
6689                } else {
6690                    final boolean isDep = app.pkgDeps != null
6691                            && app.pkgDeps.contains(packageName);
6692                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6693                        continue;
6694                    }
6695                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6696                        continue;
6697                    }
6698                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6699                        continue;
6700                    }
6701                }
6702
6703                // Process has passed all conditions, kill it!
6704                if (!doit) {
6705                    return true;
6706                }
6707                app.removed = true;
6708                procs.add(app);
6709            }
6710        }
6711
6712        int N = procs.size();
6713        for (int i=0; i<N; i++) {
6714            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6715        }
6716        updateOomAdjLocked();
6717        return N > 0;
6718    }
6719
6720    private void cleanupDisabledPackageComponentsLocked(
6721            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6722
6723        Set<String> disabledClasses = null;
6724        boolean packageDisabled = false;
6725        IPackageManager pm = AppGlobals.getPackageManager();
6726
6727        if (changedClasses == null) {
6728            // Nothing changed...
6729            return;
6730        }
6731
6732        // Determine enable/disable state of the package and its components.
6733        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6734        for (int i = changedClasses.length - 1; i >= 0; i--) {
6735            final String changedClass = changedClasses[i];
6736
6737            if (changedClass.equals(packageName)) {
6738                try {
6739                    // Entire package setting changed
6740                    enabled = pm.getApplicationEnabledSetting(packageName,
6741                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6742                } catch (Exception e) {
6743                    // No such package/component; probably racing with uninstall.  In any
6744                    // event it means we have nothing further to do here.
6745                    return;
6746                }
6747                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6748                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6749                if (packageDisabled) {
6750                    // Entire package is disabled.
6751                    // No need to continue to check component states.
6752                    disabledClasses = null;
6753                    break;
6754                }
6755            } else {
6756                try {
6757                    enabled = pm.getComponentEnabledSetting(
6758                            new ComponentName(packageName, changedClass),
6759                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6760                } catch (Exception e) {
6761                    // As above, probably racing with uninstall.
6762                    return;
6763                }
6764                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6765                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6766                    if (disabledClasses == null) {
6767                        disabledClasses = new ArraySet<>(changedClasses.length);
6768                    }
6769                    disabledClasses.add(changedClass);
6770                }
6771            }
6772        }
6773
6774        if (!packageDisabled && disabledClasses == null) {
6775            // Nothing to do here...
6776            return;
6777        }
6778
6779        // Clean-up disabled activities.
6780        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6781                packageName, disabledClasses, true, false, userId) && mBooted) {
6782            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6783            mStackSupervisor.scheduleIdleLocked();
6784        }
6785
6786        // Clean-up disabled tasks
6787        mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6788
6789        // Clean-up disabled services.
6790        mServices.bringDownDisabledPackageServicesLocked(
6791                packageName, disabledClasses, userId, false, killProcess, true);
6792
6793        // Clean-up disabled providers.
6794        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6795        mProviderMap.collectPackageProvidersLocked(
6796                packageName, disabledClasses, true, false, userId, providers);
6797        for (int i = providers.size() - 1; i >= 0; i--) {
6798            removeDyingProviderLocked(null, providers.get(i), true);
6799        }
6800
6801        // Clean-up disabled broadcast receivers.
6802        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6803            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6804                    packageName, disabledClasses, userId, true);
6805        }
6806
6807    }
6808
6809    final boolean clearBroadcastQueueForUserLocked(int userId) {
6810        boolean didSomething = false;
6811        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6812            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6813                    null, null, userId, true);
6814        }
6815        return didSomething;
6816    }
6817
6818    final boolean forceStopPackageLocked(String packageName, int appId,
6819            boolean callerWillRestart, boolean purgeCache, boolean doit,
6820            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6821        int i;
6822
6823        if (userId == UserHandle.USER_ALL && packageName == null) {
6824            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6825        }
6826
6827        if (appId < 0 && packageName != null) {
6828            try {
6829                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6830                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6831            } catch (RemoteException e) {
6832            }
6833        }
6834
6835        if (doit) {
6836            if (packageName != null) {
6837                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6838                        + " user=" + userId + ": " + reason);
6839            } else {
6840                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6841            }
6842
6843            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6844        }
6845
6846        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6847                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6848                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6849
6850        didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
6851
6852        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6853                packageName, null, doit, evenPersistent, userId)) {
6854            if (!doit) {
6855                return true;
6856            }
6857            didSomething = true;
6858        }
6859
6860        if (mServices.bringDownDisabledPackageServicesLocked(
6861                packageName, null, userId, evenPersistent, true, doit)) {
6862            if (!doit) {
6863                return true;
6864            }
6865            didSomething = true;
6866        }
6867
6868        if (packageName == null) {
6869            // Remove all sticky broadcasts from this user.
6870            mStickyBroadcasts.remove(userId);
6871        }
6872
6873        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6874        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6875                userId, providers)) {
6876            if (!doit) {
6877                return true;
6878            }
6879            didSomething = true;
6880        }
6881        for (i = providers.size() - 1; i >= 0; i--) {
6882            removeDyingProviderLocked(null, providers.get(i), true);
6883        }
6884
6885        // Remove transient permissions granted from/to this package/user
6886        removeUriPermissionsForPackageLocked(packageName, userId, false);
6887
6888        if (doit) {
6889            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6890                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6891                        packageName, null, userId, doit);
6892            }
6893        }
6894
6895        if (packageName == null || uninstalling) {
6896            // Remove pending intents.  For now we only do this when force
6897            // stopping users, because we have some problems when doing this
6898            // for packages -- app widgets are not currently cleaned up for
6899            // such packages, so they can be left with bad pending intents.
6900            if (mIntentSenderRecords.size() > 0) {
6901                Iterator<WeakReference<PendingIntentRecord>> it
6902                        = mIntentSenderRecords.values().iterator();
6903                while (it.hasNext()) {
6904                    WeakReference<PendingIntentRecord> wpir = it.next();
6905                    if (wpir == null) {
6906                        it.remove();
6907                        continue;
6908                    }
6909                    PendingIntentRecord pir = wpir.get();
6910                    if (pir == null) {
6911                        it.remove();
6912                        continue;
6913                    }
6914                    if (packageName == null) {
6915                        // Stopping user, remove all objects for the user.
6916                        if (pir.key.userId != userId) {
6917                            // Not the same user, skip it.
6918                            continue;
6919                        }
6920                    } else {
6921                        if (UserHandle.getAppId(pir.uid) != appId) {
6922                            // Different app id, skip it.
6923                            continue;
6924                        }
6925                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6926                            // Different user, skip it.
6927                            continue;
6928                        }
6929                        if (!pir.key.packageName.equals(packageName)) {
6930                            // Different package, skip it.
6931                            continue;
6932                        }
6933                    }
6934                    if (!doit) {
6935                        return true;
6936                    }
6937                    didSomething = true;
6938                    it.remove();
6939                    makeIntentSenderCanceledLocked(pir);
6940                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6941                        pir.key.activity.pendingResults.remove(pir.ref);
6942                    }
6943                }
6944            }
6945        }
6946
6947        if (doit) {
6948            if (purgeCache && packageName != null) {
6949                AttributeCache ac = AttributeCache.instance();
6950                if (ac != null) {
6951                    ac.removePackage(packageName);
6952                }
6953            }
6954            if (mBooted) {
6955                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6956                mStackSupervisor.scheduleIdleLocked();
6957            }
6958        }
6959
6960        return didSomething;
6961    }
6962
6963    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6964        return removeProcessNameLocked(name, uid, null);
6965    }
6966
6967    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6968            final ProcessRecord expecting) {
6969        ProcessRecord old = mProcessNames.get(name, uid);
6970        // Only actually remove when the currently recorded value matches the
6971        // record that we expected; if it doesn't match then we raced with a
6972        // newly created process and we don't want to destroy the new one.
6973        if ((expecting == null) || (old == expecting)) {
6974            mProcessNames.remove(name, uid);
6975        }
6976        if (old != null && old.uidRecord != null) {
6977            old.uidRecord.numProcs--;
6978            if (old.uidRecord.numProcs == 0) {
6979                // No more processes using this uid, tell clients it is gone.
6980                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6981                        "No more processes in " + old.uidRecord);
6982                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6983                EventLogTags.writeAmUidStopped(uid);
6984                mActiveUids.remove(uid);
6985                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6986            }
6987            old.uidRecord = null;
6988        }
6989        mIsolatedProcesses.remove(uid);
6990        return old;
6991    }
6992
6993    private final void addProcessNameLocked(ProcessRecord proc) {
6994        // We shouldn't already have a process under this name, but just in case we
6995        // need to clean up whatever may be there now.
6996        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6997        if (old == proc && proc.persistent) {
6998            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6999            Slog.w(TAG, "Re-adding persistent process " + proc);
7000        } else if (old != null) {
7001            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
7002        }
7003        UidRecord uidRec = mActiveUids.get(proc.uid);
7004        if (uidRec == null) {
7005            uidRec = new UidRecord(proc.uid);
7006            // This is the first appearance of the uid, report it now!
7007            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7008                    "Creating new process uid: " + uidRec);
7009            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
7010                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
7011                uidRec.setWhitelist = uidRec.curWhitelist = true;
7012            }
7013            uidRec.updateHasInternetPermission();
7014            mActiveUids.put(proc.uid, uidRec);
7015            EventLogTags.writeAmUidRunning(uidRec.uid);
7016            noteUidProcessState(uidRec.uid, uidRec.curProcState);
7017        }
7018        proc.uidRecord = uidRec;
7019
7020        // Reset render thread tid if it was already set, so new process can set it again.
7021        proc.renderThreadTid = 0;
7022        uidRec.numProcs++;
7023        mProcessNames.put(proc.processName, proc.uid, proc);
7024        if (proc.isolated) {
7025            mIsolatedProcesses.put(proc.uid, proc);
7026        }
7027    }
7028
7029    boolean removeProcessLocked(ProcessRecord app,
7030            boolean callerWillRestart, boolean allowRestart, String reason) {
7031        final String name = app.processName;
7032        final int uid = app.uid;
7033        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
7034            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
7035
7036        ProcessRecord old = mProcessNames.get(name, uid);
7037        if (old != app) {
7038            // This process is no longer active, so nothing to do.
7039            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
7040            return false;
7041        }
7042        removeProcessNameLocked(name, uid);
7043        if (mHeavyWeightProcess == app) {
7044            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7045                    mHeavyWeightProcess.userId, 0));
7046            mHeavyWeightProcess = null;
7047        }
7048        boolean needRestart = false;
7049        if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
7050            int pid = app.pid;
7051            if (pid > 0) {
7052                synchronized (mPidsSelfLocked) {
7053                    mPidsSelfLocked.remove(pid);
7054                    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7055                }
7056                mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7057                if (app.isolated) {
7058                    mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7059                    getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
7060                }
7061            }
7062            boolean willRestart = false;
7063            if (app.persistent && !app.isolated) {
7064                if (!callerWillRestart) {
7065                    willRestart = true;
7066                } else {
7067                    needRestart = true;
7068                }
7069            }
7070            app.kill(reason, true);
7071            handleAppDiedLocked(app, willRestart, allowRestart);
7072            if (willRestart) {
7073                removeLruProcessLocked(app);
7074                addAppLocked(app.info, null, false, null /* ABI override */);
7075            }
7076        } else {
7077            mRemovedProcesses.add(app);
7078        }
7079
7080        return needRestart;
7081    }
7082
7083    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
7084        cleanupAppInLaunchingProvidersLocked(app, true);
7085        removeProcessLocked(app, false, true, "timeout publishing content providers");
7086    }
7087
7088    private final void processStartTimedOutLocked(ProcessRecord app) {
7089        final int pid = app.pid;
7090        boolean gone = false;
7091        synchronized (mPidsSelfLocked) {
7092            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
7093            if (knownApp != null && knownApp.thread == null) {
7094                mPidsSelfLocked.remove(pid);
7095                gone = true;
7096            }
7097        }
7098
7099        if (gone) {
7100            Slog.w(TAG, "Process " + app + " failed to attach");
7101            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
7102                    pid, app.uid, app.processName);
7103            removeProcessNameLocked(app.processName, app.uid);
7104            if (mHeavyWeightProcess == app) {
7105                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7106                        mHeavyWeightProcess.userId, 0));
7107                mHeavyWeightProcess = null;
7108            }
7109            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7110            // Take care of any launching providers waiting for this process.
7111            cleanupAppInLaunchingProvidersLocked(app, true);
7112            // Take care of any services that are waiting for the process.
7113            mServices.processStartTimedOutLocked(app);
7114            app.kill("start timeout", true);
7115            if (app.isolated) {
7116                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7117            }
7118            removeLruProcessLocked(app);
7119            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
7120                Slog.w(TAG, "Unattached app died before backup, skipping");
7121                mHandler.post(new Runnable() {
7122                @Override
7123                    public void run(){
7124                        try {
7125                            IBackupManager bm = IBackupManager.Stub.asInterface(
7126                                    ServiceManager.getService(Context.BACKUP_SERVICE));
7127                            bm.agentDisconnected(app.info.packageName);
7128                        } catch (RemoteException e) {
7129                            // Can't happen; the backup manager is local
7130                        }
7131                    }
7132                });
7133            }
7134            if (isPendingBroadcastProcessLocked(pid)) {
7135                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
7136                skipPendingBroadcastLocked(pid);
7137            }
7138        } else {
7139            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
7140        }
7141    }
7142
7143    private final boolean attachApplicationLocked(IApplicationThread thread,
7144            int pid, int callingUid, long startSeq) {
7145
7146        // Find the application record that is being attached...  either via
7147        // the pid if we are running in multiple processes, or just pull the
7148        // next app record if we are emulating process with anonymous threads.
7149        ProcessRecord app;
7150        long startTime = SystemClock.uptimeMillis();
7151        if (pid != MY_PID && pid >= 0) {
7152            synchronized (mPidsSelfLocked) {
7153                app = mPidsSelfLocked.get(pid);
7154            }
7155        } else {
7156            app = null;
7157        }
7158
7159        // It's possible that process called attachApplication before we got a chance to
7160        // update the internal state.
7161        if (app == null && startSeq > 0) {
7162            final ProcessRecord pending = mPendingStarts.get(startSeq);
7163            if (pending != null && pending.startUid == callingUid
7164                    && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
7165                            startSeq, true)) {
7166                app = pending;
7167            }
7168        }
7169
7170        if (app == null) {
7171            Slog.w(TAG, "No pending application record for pid " + pid
7172                    + " (IApplicationThread " + thread + "); dropping process");
7173            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
7174            if (pid > 0 && pid != MY_PID) {
7175                killProcessQuiet(pid);
7176                //TODO: killProcessGroup(app.info.uid, pid);
7177            } else {
7178                try {
7179                    thread.scheduleExit();
7180                } catch (Exception e) {
7181                    // Ignore exceptions.
7182                }
7183            }
7184            return false;
7185        }
7186
7187        // If this application record is still attached to a previous
7188        // process, clean it up now.
7189        if (app.thread != null) {
7190            handleAppDiedLocked(app, true, true);
7191        }
7192
7193        // Tell the process all about itself.
7194
7195        if (DEBUG_ALL) Slog.v(
7196                TAG, "Binding process pid " + pid + " to record " + app);
7197
7198        final String processName = app.processName;
7199        try {
7200            AppDeathRecipient adr = new AppDeathRecipient(
7201                    app, pid, thread);
7202            thread.asBinder().linkToDeath(adr, 0);
7203            app.deathRecipient = adr;
7204        } catch (RemoteException e) {
7205            app.resetPackageList(mProcessStats);
7206            startProcessLocked(app, "link fail", processName);
7207            return false;
7208        }
7209
7210        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
7211
7212        app.makeActive(thread, mProcessStats);
7213        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
7214        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
7215        app.forcingToImportant = null;
7216        updateProcessForegroundLocked(app, false, false);
7217        app.hasShownUi = false;
7218        app.debugging = false;
7219        app.cached = false;
7220        app.killedByAm = false;
7221        app.killed = false;
7222
7223
7224        // We carefully use the same state that PackageManager uses for
7225        // filtering, since we use this flag to decide if we need to install
7226        // providers when user is unlocked later
7227        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
7228
7229        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7230
7231        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
7232        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7233
7234        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7235            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7236            msg.obj = app;
7237            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7238        }
7239
7240        checkTime(startTime, "attachApplicationLocked: before bindApplication");
7241
7242        if (!normalMode) {
7243            Slog.i(TAG, "Launching preboot mode app: " + app);
7244        }
7245
7246        if (DEBUG_ALL) Slog.v(
7247            TAG, "New app record " + app
7248            + " thread=" + thread.asBinder() + " pid=" + pid);
7249        try {
7250            int testMode = ApplicationThreadConstants.DEBUG_OFF;
7251            if (mDebugApp != null && mDebugApp.equals(processName)) {
7252                testMode = mWaitForDebugger
7253                    ? ApplicationThreadConstants.DEBUG_WAIT
7254                    : ApplicationThreadConstants.DEBUG_ON;
7255                app.debugging = true;
7256                if (mDebugTransient) {
7257                    mDebugApp = mOrigDebugApp;
7258                    mWaitForDebugger = mOrigWaitForDebugger;
7259                }
7260            }
7261
7262            ProfilerInfo profilerInfo = null;
7263            String preBindAgent = null;
7264            if (mProfileApp != null && mProfileApp.equals(processName)) {
7265                mProfileProc = app;
7266                if (mProfilerInfo != null) {
7267                    // Send a profiler info object to the app if either a file is given, or
7268                    // an agent should be loaded at bind-time.
7269                    boolean needsInfo = mProfilerInfo.profileFile != null
7270                            || mProfilerInfo.attachAgentDuringBind;
7271                    profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7272                    if (!mProfilerInfo.attachAgentDuringBind) {
7273                        preBindAgent = mProfilerInfo.agent;
7274                    }
7275                }
7276            } else if (app.instr != null && app.instr.mProfileFile != null) {
7277                profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7278                        null, false);
7279            }
7280
7281            boolean enableTrackAllocation = false;
7282            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7283                enableTrackAllocation = true;
7284                mTrackAllocationApp = null;
7285            }
7286
7287            // If the app is being launched for restore or full backup, set it up specially
7288            boolean isRestrictedBackupMode = false;
7289            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7290                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7291                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7292                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7293                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7294            }
7295
7296            if (app.instr != null) {
7297                notifyPackageUse(app.instr.mClass.getPackageName(),
7298                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7299            }
7300            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7301                    + processName + " with config " + getGlobalConfiguration());
7302            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7303            app.compat = compatibilityInfoForPackageLocked(appInfo);
7304
7305            if (profilerInfo != null && profilerInfo.profileFd != null) {
7306                profilerInfo.profileFd = profilerInfo.profileFd.dup();
7307            }
7308
7309            // We deprecated Build.SERIAL and it is not accessible to
7310            // apps that target the v2 security sandbox and to apps that
7311            // target APIs higher than O MR1. Since access to the serial
7312            // is now behind a permission we push down the value.
7313            final String buildSerial = (appInfo.targetSandboxVersion < 2
7314                    && appInfo.targetSdkVersion <= Build.VERSION_CODES.O_MR1)
7315                            ? sTheRealBuildSerial : Build.UNKNOWN;
7316
7317            // Check if this is a secondary process that should be incorporated into some
7318            // currently active instrumentation.  (Note we do this AFTER all of the profiling
7319            // stuff above because profiling can currently happen only in the primary
7320            // instrumentation process.)
7321            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7322                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7323                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7324                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7325                        if (aInstr.mTargetProcesses.length == 0) {
7326                            // This is the wildcard mode, where every process brought up for
7327                            // the target instrumentation should be included.
7328                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7329                                app.instr = aInstr;
7330                                aInstr.mRunningProcesses.add(app);
7331                            }
7332                        } else {
7333                            for (String proc : aInstr.mTargetProcesses) {
7334                                if (proc.equals(app.processName)) {
7335                                    app.instr = aInstr;
7336                                    aInstr.mRunningProcesses.add(app);
7337                                    break;
7338                                }
7339                            }
7340                        }
7341                    }
7342                }
7343            }
7344
7345            // If we were asked to attach an agent on startup, do so now, before we're binding
7346            // application code.
7347            if (preBindAgent != null) {
7348                thread.attachAgent(preBindAgent);
7349            }
7350
7351            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7352            mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
7353            if (app.isolatedEntryPoint != null) {
7354                // This is an isolated process which should just call an entry point instead of
7355                // being bound to an application.
7356                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7357            } else if (app.instr != null) {
7358                thread.bindApplication(processName, appInfo, providers,
7359                        app.instr.mClass,
7360                        profilerInfo, app.instr.mArguments,
7361                        app.instr.mWatcher,
7362                        app.instr.mUiAutomationConnection, testMode,
7363                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7364                        isRestrictedBackupMode || !normalMode, app.persistent,
7365                        new Configuration(getGlobalConfiguration()), app.compat,
7366                        getCommonServicesLocked(app.isolated),
7367                        mCoreSettingsObserver.getCoreSettingsLocked(),
7368                        buildSerial);
7369            } else {
7370                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7371                        null, null, null, testMode,
7372                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7373                        isRestrictedBackupMode || !normalMode, app.persistent,
7374                        new Configuration(getGlobalConfiguration()), app.compat,
7375                        getCommonServicesLocked(app.isolated),
7376                        mCoreSettingsObserver.getCoreSettingsLocked(),
7377                        buildSerial);
7378            }
7379
7380            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7381            updateLruProcessLocked(app, false, null);
7382            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7383            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7384        } catch (Exception e) {
7385            // todo: Yikes!  What should we do?  For now we will try to
7386            // start another process, but that could easily get us in
7387            // an infinite loop of restarting processes...
7388            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7389
7390            app.resetPackageList(mProcessStats);
7391            app.unlinkDeathRecipient();
7392            startProcessLocked(app, "bind fail", processName);
7393            return false;
7394        }
7395
7396        // Remove this record from the list of starting applications.
7397        mPersistentStartingProcesses.remove(app);
7398        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7399                "Attach application locked removing on hold: " + app);
7400        mProcessesOnHold.remove(app);
7401
7402        boolean badApp = false;
7403        boolean didSomething = false;
7404
7405        // See if the top visible activity is waiting to run in this process...
7406        if (normalMode) {
7407            try {
7408                if (mStackSupervisor.attachApplicationLocked(app)) {
7409                    didSomething = true;
7410                }
7411            } catch (Exception e) {
7412                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7413                badApp = true;
7414            }
7415        }
7416
7417        // Find any services that should be running in this process...
7418        if (!badApp) {
7419            try {
7420                didSomething |= mServices.attachApplicationLocked(app, processName);
7421                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7422            } catch (Exception e) {
7423                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7424                badApp = true;
7425            }
7426        }
7427
7428        // Check if a next-broadcast receiver is in this process...
7429        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7430            try {
7431                didSomething |= sendPendingBroadcastsLocked(app);
7432                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7433            } catch (Exception e) {
7434                // If the app died trying to launch the receiver we declare it 'bad'
7435                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7436                badApp = true;
7437            }
7438        }
7439
7440        // Check whether the next backup agent is in this process...
7441        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7442            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7443                    "New app is backup target, launching agent for " + app);
7444            notifyPackageUse(mBackupTarget.appInfo.packageName,
7445                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7446            try {
7447                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7448                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7449                        mBackupTarget.backupMode);
7450            } catch (Exception e) {
7451                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7452                badApp = true;
7453            }
7454        }
7455
7456        if (badApp) {
7457            app.kill("error during init", true);
7458            handleAppDiedLocked(app, false, true);
7459            return false;
7460        }
7461
7462        if (!didSomething) {
7463            updateOomAdjLocked();
7464            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7465        }
7466
7467        return true;
7468    }
7469
7470    @Override
7471    public final void attachApplication(IApplicationThread thread, long startSeq) {
7472        synchronized (this) {
7473            int callingPid = Binder.getCallingPid();
7474            final int callingUid = Binder.getCallingUid();
7475            final long origId = Binder.clearCallingIdentity();
7476            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
7477            Binder.restoreCallingIdentity(origId);
7478        }
7479    }
7480
7481    @Override
7482    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7483        final long origId = Binder.clearCallingIdentity();
7484        synchronized (this) {
7485            ActivityStack stack = ActivityRecord.getStackLocked(token);
7486            if (stack != null) {
7487                ActivityRecord r =
7488                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7489                                false /* processPausingActivities */, config);
7490                if (stopProfiling) {
7491                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
7492                        clearProfilerLocked();
7493                    }
7494                }
7495            }
7496        }
7497        Binder.restoreCallingIdentity(origId);
7498    }
7499
7500    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7501        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7502                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7503    }
7504
7505    void enableScreenAfterBoot() {
7506        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7507                SystemClock.uptimeMillis());
7508        mWindowManager.enableScreenAfterBoot();
7509
7510        synchronized (this) {
7511            updateEventDispatchingLocked();
7512        }
7513    }
7514
7515    @Override
7516    public void showBootMessage(final CharSequence msg, final boolean always) {
7517        if (Binder.getCallingUid() != myUid()) {
7518            throw new SecurityException();
7519        }
7520        mWindowManager.showBootMessage(msg, always);
7521    }
7522
7523    @Override
7524    public void keyguardGoingAway(int flags) {
7525        enforceNotIsolatedCaller("keyguardGoingAway");
7526        final long token = Binder.clearCallingIdentity();
7527        try {
7528            synchronized (this) {
7529                mKeyguardController.keyguardGoingAway(flags);
7530            }
7531        } finally {
7532            Binder.restoreCallingIdentity(token);
7533        }
7534    }
7535
7536    /**
7537     * @return whther the keyguard is currently locked.
7538     */
7539    boolean isKeyguardLocked() {
7540        return mKeyguardController.isKeyguardLocked();
7541    }
7542
7543    final void finishBooting() {
7544        synchronized (this) {
7545            if (!mBootAnimationComplete) {
7546                mCallFinishBooting = true;
7547                return;
7548            }
7549            mCallFinishBooting = false;
7550        }
7551
7552        ArraySet<String> completedIsas = new ArraySet<String>();
7553        for (String abi : Build.SUPPORTED_ABIS) {
7554            zygoteProcess.establishZygoteConnectionForAbi(abi);
7555            final String instructionSet = VMRuntime.getInstructionSet(abi);
7556            if (!completedIsas.contains(instructionSet)) {
7557                try {
7558                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7559                } catch (InstallerException e) {
7560                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7561                            e.getMessage() +")");
7562                }
7563                completedIsas.add(instructionSet);
7564            }
7565        }
7566
7567        IntentFilter pkgFilter = new IntentFilter();
7568        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7569        pkgFilter.addDataScheme("package");
7570        mContext.registerReceiver(new BroadcastReceiver() {
7571            @Override
7572            public void onReceive(Context context, Intent intent) {
7573                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7574                if (pkgs != null) {
7575                    for (String pkg : pkgs) {
7576                        synchronized (ActivityManagerService.this) {
7577                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7578                                    0, "query restart")) {
7579                                setResultCode(Activity.RESULT_OK);
7580                                return;
7581                            }
7582                        }
7583                    }
7584                }
7585            }
7586        }, pkgFilter);
7587
7588        IntentFilter dumpheapFilter = new IntentFilter();
7589        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7590        mContext.registerReceiver(new BroadcastReceiver() {
7591            @Override
7592            public void onReceive(Context context, Intent intent) {
7593                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7594                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7595                } else {
7596                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7597                }
7598            }
7599        }, dumpheapFilter);
7600
7601        // Let system services know.
7602        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7603
7604        synchronized (this) {
7605            // Ensure that any processes we had put on hold are now started
7606            // up.
7607            final int NP = mProcessesOnHold.size();
7608            if (NP > 0) {
7609                ArrayList<ProcessRecord> procs =
7610                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7611                for (int ip=0; ip<NP; ip++) {
7612                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7613                            + procs.get(ip));
7614                    startProcessLocked(procs.get(ip), "on-hold", null);
7615                }
7616            }
7617            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7618                return;
7619            }
7620            // Start looking for apps that are abusing wake locks.
7621            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7622            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7623            // Tell anyone interested that we are done booting!
7624            SystemProperties.set("sys.boot_completed", "1");
7625
7626            // And trigger dev.bootcomplete if we are not showing encryption progress
7627            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7628                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7629                SystemProperties.set("dev.bootcomplete", "1");
7630            }
7631            mUserController.sendBootCompleted(
7632                    new IIntentReceiver.Stub() {
7633                        @Override
7634                        public void performReceive(Intent intent, int resultCode,
7635                                String data, Bundle extras, boolean ordered,
7636                                boolean sticky, int sendingUser) {
7637                            synchronized (ActivityManagerService.this) {
7638                                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
7639                            }
7640                        }
7641                    });
7642            mUserController.scheduleStartProfiles();
7643        }
7644    }
7645
7646    @Override
7647    public void bootAnimationComplete() {
7648        final boolean callFinishBooting;
7649        synchronized (this) {
7650            callFinishBooting = mCallFinishBooting;
7651            mBootAnimationComplete = true;
7652        }
7653        if (callFinishBooting) {
7654            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7655            finishBooting();
7656            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7657        }
7658    }
7659
7660    final void ensureBootCompleted() {
7661        boolean booting;
7662        boolean enableScreen;
7663        synchronized (this) {
7664            booting = mBooting;
7665            mBooting = false;
7666            enableScreen = !mBooted;
7667            mBooted = true;
7668        }
7669
7670        if (booting) {
7671            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7672            finishBooting();
7673            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7674        }
7675
7676        if (enableScreen) {
7677            enableScreenAfterBoot();
7678        }
7679    }
7680
7681    @Override
7682    public final void activityResumed(IBinder token) {
7683        final long origId = Binder.clearCallingIdentity();
7684        synchronized(this) {
7685            ActivityRecord.activityResumedLocked(token);
7686            mWindowManager.notifyAppResumedFinished(token);
7687        }
7688        Binder.restoreCallingIdentity(origId);
7689    }
7690
7691    @Override
7692    public final void activityPaused(IBinder token) {
7693        final long origId = Binder.clearCallingIdentity();
7694        synchronized(this) {
7695            ActivityStack stack = ActivityRecord.getStackLocked(token);
7696            if (stack != null) {
7697                stack.activityPausedLocked(token, false);
7698            }
7699        }
7700        Binder.restoreCallingIdentity(origId);
7701    }
7702
7703    @Override
7704    public final void activityStopped(IBinder token, Bundle icicle,
7705            PersistableBundle persistentState, CharSequence description) {
7706        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7707
7708        // Refuse possible leaked file descriptors
7709        if (icicle != null && icicle.hasFileDescriptors()) {
7710            throw new IllegalArgumentException("File descriptors passed in Bundle");
7711        }
7712
7713        final long origId = Binder.clearCallingIdentity();
7714
7715        synchronized (this) {
7716            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7717            if (r != null) {
7718                r.activityStoppedLocked(icicle, persistentState, description);
7719            }
7720        }
7721
7722        trimApplications();
7723
7724        Binder.restoreCallingIdentity(origId);
7725    }
7726
7727    @Override
7728    public final void activityDestroyed(IBinder token) {
7729        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7730        synchronized (this) {
7731            ActivityStack stack = ActivityRecord.getStackLocked(token);
7732            if (stack != null) {
7733                stack.activityDestroyedLocked(token, "activityDestroyed");
7734            }
7735        }
7736    }
7737
7738    @Override
7739    public final void activityRelaunched(IBinder token) {
7740        final long origId = Binder.clearCallingIdentity();
7741        synchronized (this) {
7742            mStackSupervisor.activityRelaunchedLocked(token);
7743        }
7744        Binder.restoreCallingIdentity(origId);
7745    }
7746
7747    @Override
7748    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7749            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7750        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7751                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7752        synchronized (this) {
7753            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7754            if (record == null) {
7755                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7756                        + "found for: " + token);
7757            }
7758            record.setSizeConfigurations(horizontalSizeConfiguration,
7759                    verticalSizeConfigurations, smallestSizeConfigurations);
7760        }
7761    }
7762
7763    @Override
7764    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7765        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7766    }
7767
7768    @Override
7769    public final void notifyEnterAnimationComplete(IBinder token) {
7770        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7771    }
7772
7773    @Override
7774    public String getCallingPackage(IBinder token) {
7775        synchronized (this) {
7776            ActivityRecord r = getCallingRecordLocked(token);
7777            return r != null ? r.info.packageName : null;
7778        }
7779    }
7780
7781    @Override
7782    public ComponentName getCallingActivity(IBinder token) {
7783        synchronized (this) {
7784            ActivityRecord r = getCallingRecordLocked(token);
7785            return r != null ? r.intent.getComponent() : null;
7786        }
7787    }
7788
7789    private ActivityRecord getCallingRecordLocked(IBinder token) {
7790        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7791        if (r == null) {
7792            return null;
7793        }
7794        return r.resultTo;
7795    }
7796
7797    @Override
7798    public ComponentName getActivityClassForToken(IBinder token) {
7799        synchronized(this) {
7800            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7801            if (r == null) {
7802                return null;
7803            }
7804            return r.intent.getComponent();
7805        }
7806    }
7807
7808    @Override
7809    public String getPackageForToken(IBinder token) {
7810        synchronized(this) {
7811            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7812            if (r == null) {
7813                return null;
7814            }
7815            return r.packageName;
7816        }
7817    }
7818
7819    @Override
7820    public boolean isRootVoiceInteraction(IBinder token) {
7821        synchronized(this) {
7822            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7823            if (r == null) {
7824                return false;
7825            }
7826            return r.rootVoiceInteraction;
7827        }
7828    }
7829
7830    @Override
7831    public IIntentSender getIntentSender(int type,
7832            String packageName, IBinder token, String resultWho,
7833            int requestCode, Intent[] intents, String[] resolvedTypes,
7834            int flags, Bundle bOptions, int userId) {
7835        enforceNotIsolatedCaller("getIntentSender");
7836        // Refuse possible leaked file descriptors
7837        if (intents != null) {
7838            if (intents.length < 1) {
7839                throw new IllegalArgumentException("Intents array length must be >= 1");
7840            }
7841            for (int i=0; i<intents.length; i++) {
7842                Intent intent = intents[i];
7843                if (intent != null) {
7844                    if (intent.hasFileDescriptors()) {
7845                        throw new IllegalArgumentException("File descriptors passed in Intent");
7846                    }
7847                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7848                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7849                        throw new IllegalArgumentException(
7850                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7851                    }
7852                    intents[i] = new Intent(intent);
7853                }
7854            }
7855            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7856                throw new IllegalArgumentException(
7857                        "Intent array length does not match resolvedTypes length");
7858            }
7859        }
7860        if (bOptions != null) {
7861            if (bOptions.hasFileDescriptors()) {
7862                throw new IllegalArgumentException("File descriptors passed in options");
7863            }
7864        }
7865
7866        synchronized(this) {
7867            int callingUid = Binder.getCallingUid();
7868            int origUserId = userId;
7869            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7870                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7871                    ALLOW_NON_FULL, "getIntentSender", null);
7872            if (origUserId == UserHandle.USER_CURRENT) {
7873                // We don't want to evaluate this until the pending intent is
7874                // actually executed.  However, we do want to always do the
7875                // security checking for it above.
7876                userId = UserHandle.USER_CURRENT;
7877            }
7878            try {
7879                if (callingUid != 0 && callingUid != SYSTEM_UID) {
7880                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7881                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7882                    if (!UserHandle.isSameApp(callingUid, uid)) {
7883                        String msg = "Permission Denial: getIntentSender() from pid="
7884                            + Binder.getCallingPid()
7885                            + ", uid=" + Binder.getCallingUid()
7886                            + ", (need uid=" + uid + ")"
7887                            + " is not allowed to send as package " + packageName;
7888                        Slog.w(TAG, msg);
7889                        throw new SecurityException(msg);
7890                    }
7891                }
7892
7893                return getIntentSenderLocked(type, packageName, callingUid, userId,
7894                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7895
7896            } catch (RemoteException e) {
7897                throw new SecurityException(e);
7898            }
7899        }
7900    }
7901
7902    IIntentSender getIntentSenderLocked(int type, String packageName,
7903            int callingUid, int userId, IBinder token, String resultWho,
7904            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7905            Bundle bOptions) {
7906        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7907        ActivityRecord activity = null;
7908        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7909            activity = ActivityRecord.isInStackLocked(token);
7910            if (activity == null) {
7911                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7912                return null;
7913            }
7914            if (activity.finishing) {
7915                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7916                return null;
7917            }
7918        }
7919
7920        // We're going to be splicing together extras before sending, so we're
7921        // okay poking into any contained extras.
7922        if (intents != null) {
7923            for (int i = 0; i < intents.length; i++) {
7924                intents[i].setDefusable(true);
7925            }
7926        }
7927        Bundle.setDefusable(bOptions, true);
7928
7929        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7930        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7931        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7932        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7933                |PendingIntent.FLAG_UPDATE_CURRENT);
7934
7935        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7936                type, packageName, activity, resultWho,
7937                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7938        WeakReference<PendingIntentRecord> ref;
7939        ref = mIntentSenderRecords.get(key);
7940        PendingIntentRecord rec = ref != null ? ref.get() : null;
7941        if (rec != null) {
7942            if (!cancelCurrent) {
7943                if (updateCurrent) {
7944                    if (rec.key.requestIntent != null) {
7945                        rec.key.requestIntent.replaceExtras(intents != null ?
7946                                intents[intents.length - 1] : null);
7947                    }
7948                    if (intents != null) {
7949                        intents[intents.length-1] = rec.key.requestIntent;
7950                        rec.key.allIntents = intents;
7951                        rec.key.allResolvedTypes = resolvedTypes;
7952                    } else {
7953                        rec.key.allIntents = null;
7954                        rec.key.allResolvedTypes = null;
7955                    }
7956                }
7957                return rec;
7958            }
7959            makeIntentSenderCanceledLocked(rec);
7960            mIntentSenderRecords.remove(key);
7961        }
7962        if (noCreate) {
7963            return rec;
7964        }
7965        rec = new PendingIntentRecord(this, key, callingUid);
7966        mIntentSenderRecords.put(key, rec.ref);
7967        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7968            if (activity.pendingResults == null) {
7969                activity.pendingResults
7970                        = new HashSet<WeakReference<PendingIntentRecord>>();
7971            }
7972            activity.pendingResults.add(rec.ref);
7973        }
7974        return rec;
7975    }
7976
7977    @Override
7978    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7979            Intent intent, String resolvedType,
7980            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7981        if (target instanceof PendingIntentRecord) {
7982            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7983                    whitelistToken, finishedReceiver, requiredPermission, options);
7984        } else {
7985            if (intent == null) {
7986                // Weird case: someone has given us their own custom IIntentSender, and now
7987                // they have someone else trying to send to it but of course this isn't
7988                // really a PendingIntent, so there is no base Intent, and the caller isn't
7989                // supplying an Intent... but we never want to dispatch a null Intent to
7990                // a receiver, so um...  let's make something up.
7991                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7992                intent = new Intent(Intent.ACTION_MAIN);
7993            }
7994            try {
7995                target.send(code, intent, resolvedType, whitelistToken, null,
7996                        requiredPermission, options);
7997            } catch (RemoteException e) {
7998            }
7999            // Platform code can rely on getting a result back when the send is done, but if
8000            // this intent sender is from outside of the system we can't rely on it doing that.
8001            // So instead we don't give it the result receiver, and instead just directly
8002            // report the finish immediately.
8003            if (finishedReceiver != null) {
8004                try {
8005                    finishedReceiver.performReceive(intent, 0,
8006                            null, null, false, false, UserHandle.getCallingUserId());
8007                } catch (RemoteException e) {
8008                }
8009            }
8010            return 0;
8011        }
8012    }
8013
8014    @Override
8015    public void cancelIntentSender(IIntentSender sender) {
8016        if (!(sender instanceof PendingIntentRecord)) {
8017            return;
8018        }
8019        synchronized(this) {
8020            PendingIntentRecord rec = (PendingIntentRecord)sender;
8021            try {
8022                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
8023                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
8024                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
8025                    String msg = "Permission Denial: cancelIntentSender() from pid="
8026                        + Binder.getCallingPid()
8027                        + ", uid=" + Binder.getCallingUid()
8028                        + " is not allowed to cancel package "
8029                        + rec.key.packageName;
8030                    Slog.w(TAG, msg);
8031                    throw new SecurityException(msg);
8032                }
8033            } catch (RemoteException e) {
8034                throw new SecurityException(e);
8035            }
8036            cancelIntentSenderLocked(rec, true);
8037        }
8038    }
8039
8040    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
8041        makeIntentSenderCanceledLocked(rec);
8042        mIntentSenderRecords.remove(rec.key);
8043        if (cleanActivity && rec.key.activity != null) {
8044            rec.key.activity.pendingResults.remove(rec.ref);
8045        }
8046    }
8047
8048    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
8049        rec.canceled = true;
8050        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
8051        if (callbacks != null) {
8052            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
8053        }
8054    }
8055
8056    @Override
8057    public String getPackageForIntentSender(IIntentSender pendingResult) {
8058        if (!(pendingResult instanceof PendingIntentRecord)) {
8059            return null;
8060        }
8061        try {
8062            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8063            return res.key.packageName;
8064        } catch (ClassCastException e) {
8065        }
8066        return null;
8067    }
8068
8069    @Override
8070    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
8071        if (!(sender instanceof PendingIntentRecord)) {
8072            return;
8073        }
8074        synchronized(this) {
8075            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
8076        }
8077    }
8078
8079    @Override
8080    public void unregisterIntentSenderCancelListener(IIntentSender sender,
8081            IResultReceiver receiver) {
8082        if (!(sender instanceof PendingIntentRecord)) {
8083            return;
8084        }
8085        synchronized(this) {
8086            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
8087        }
8088    }
8089
8090    @Override
8091    public int getUidForIntentSender(IIntentSender sender) {
8092        if (sender instanceof PendingIntentRecord) {
8093            try {
8094                PendingIntentRecord res = (PendingIntentRecord)sender;
8095                return res.uid;
8096            } catch (ClassCastException e) {
8097            }
8098        }
8099        return -1;
8100    }
8101
8102    @Override
8103    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
8104        if (!(pendingResult instanceof PendingIntentRecord)) {
8105            return false;
8106        }
8107        try {
8108            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8109            if (res.key.allIntents == null) {
8110                return false;
8111            }
8112            for (int i=0; i<res.key.allIntents.length; i++) {
8113                Intent intent = res.key.allIntents[i];
8114                if (intent.getPackage() != null && intent.getComponent() != null) {
8115                    return false;
8116                }
8117            }
8118            return true;
8119        } catch (ClassCastException e) {
8120        }
8121        return false;
8122    }
8123
8124    @Override
8125    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
8126        if (!(pendingResult instanceof PendingIntentRecord)) {
8127            return false;
8128        }
8129        try {
8130            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8131            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
8132                return true;
8133            }
8134            return false;
8135        } catch (ClassCastException e) {
8136        }
8137        return false;
8138    }
8139
8140    @Override
8141    public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
8142        if (pendingResult instanceof PendingIntentRecord) {
8143            final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
8144            return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
8145        }
8146        return false;
8147    }
8148
8149    @Override
8150    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
8151        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
8152                "getIntentForIntentSender()");
8153        if (!(pendingResult instanceof PendingIntentRecord)) {
8154            return null;
8155        }
8156        try {
8157            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8158            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
8159        } catch (ClassCastException e) {
8160        }
8161        return null;
8162    }
8163
8164    @Override
8165    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
8166        if (!(pendingResult instanceof PendingIntentRecord)) {
8167            return null;
8168        }
8169        try {
8170            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8171            synchronized (this) {
8172                return getTagForIntentSenderLocked(res, prefix);
8173            }
8174        } catch (ClassCastException e) {
8175        }
8176        return null;
8177    }
8178
8179    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
8180        final Intent intent = res.key.requestIntent;
8181        if (intent != null) {
8182            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
8183                    || res.lastTagPrefix.equals(prefix))) {
8184                return res.lastTag;
8185            }
8186            res.lastTagPrefix = prefix;
8187            final StringBuilder sb = new StringBuilder(128);
8188            if (prefix != null) {
8189                sb.append(prefix);
8190            }
8191            if (intent.getAction() != null) {
8192                sb.append(intent.getAction());
8193            } else if (intent.getComponent() != null) {
8194                intent.getComponent().appendShortString(sb);
8195            } else {
8196                sb.append("?");
8197            }
8198            return res.lastTag = sb.toString();
8199        }
8200        return null;
8201    }
8202
8203    @Override
8204    public void setProcessLimit(int max) {
8205        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8206                "setProcessLimit()");
8207        synchronized (this) {
8208            mConstants.setOverrideMaxCachedProcesses(max);
8209        }
8210        trimApplications();
8211    }
8212
8213    @Override
8214    public int getProcessLimit() {
8215        synchronized (this) {
8216            return mConstants.getOverrideMaxCachedProcesses();
8217        }
8218    }
8219
8220    void importanceTokenDied(ImportanceToken token) {
8221        synchronized (ActivityManagerService.this) {
8222            synchronized (mPidsSelfLocked) {
8223                ImportanceToken cur
8224                    = mImportantProcesses.get(token.pid);
8225                if (cur != token) {
8226                    return;
8227                }
8228                mImportantProcesses.remove(token.pid);
8229                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
8230                if (pr == null) {
8231                    return;
8232                }
8233                pr.forcingToImportant = null;
8234                updateProcessForegroundLocked(pr, false, false);
8235            }
8236            updateOomAdjLocked();
8237        }
8238    }
8239
8240    @Override
8241    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8242        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8243                "setProcessImportant()");
8244        synchronized(this) {
8245            boolean changed = false;
8246
8247            synchronized (mPidsSelfLocked) {
8248                ProcessRecord pr = mPidsSelfLocked.get(pid);
8249                if (pr == null && isForeground) {
8250                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8251                    return;
8252                }
8253                ImportanceToken oldToken = mImportantProcesses.get(pid);
8254                if (oldToken != null) {
8255                    oldToken.token.unlinkToDeath(oldToken, 0);
8256                    mImportantProcesses.remove(pid);
8257                    if (pr != null) {
8258                        pr.forcingToImportant = null;
8259                    }
8260                    changed = true;
8261                }
8262                if (isForeground && token != null) {
8263                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8264                        @Override
8265                        public void binderDied() {
8266                            importanceTokenDied(this);
8267                        }
8268                    };
8269                    try {
8270                        token.linkToDeath(newToken, 0);
8271                        mImportantProcesses.put(pid, newToken);
8272                        pr.forcingToImportant = newToken;
8273                        changed = true;
8274                    } catch (RemoteException e) {
8275                        // If the process died while doing this, we will later
8276                        // do the cleanup with the process death link.
8277                    }
8278                }
8279            }
8280
8281            if (changed) {
8282                updateOomAdjLocked();
8283            }
8284        }
8285    }
8286
8287    @Override
8288    public boolean isAppForeground(int uid) throws RemoteException {
8289        synchronized (this) {
8290            UidRecord uidRec = mActiveUids.get(uid);
8291            if (uidRec == null || uidRec.idle) {
8292                return false;
8293            }
8294            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8295        }
8296    }
8297
8298    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8299    // be guarded by permission checking.
8300    int getUidState(int uid) {
8301        synchronized (this) {
8302            return getUidStateLocked(uid);
8303        }
8304    }
8305
8306    int getUidStateLocked(int uid) {
8307        UidRecord uidRec = mActiveUids.get(uid);
8308        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8309    }
8310
8311    @Override
8312    public boolean isInMultiWindowMode(IBinder token) {
8313        final long origId = Binder.clearCallingIdentity();
8314        try {
8315            synchronized(this) {
8316                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8317                if (r == null) {
8318                    return false;
8319                }
8320                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8321                return r.inMultiWindowMode();
8322            }
8323        } finally {
8324            Binder.restoreCallingIdentity(origId);
8325        }
8326    }
8327
8328    @Override
8329    public boolean isInPictureInPictureMode(IBinder token) {
8330        final long origId = Binder.clearCallingIdentity();
8331        try {
8332            synchronized(this) {
8333                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8334            }
8335        } finally {
8336            Binder.restoreCallingIdentity(origId);
8337        }
8338    }
8339
8340    private boolean isInPictureInPictureMode(ActivityRecord r) {
8341        if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8342                || r.getStack().isInStackLocked(r) == null) {
8343            return false;
8344        }
8345
8346        // If we are animating to fullscreen then we have already dispatched the PIP mode
8347        // changed, so we should reflect that check here as well.
8348        final PinnedActivityStack stack = r.getStack();
8349        final PinnedStackWindowController windowController = stack.getWindowContainerController();
8350        return !windowController.isAnimatingBoundsToFullscreen();
8351    }
8352
8353    @Override
8354    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8355        final long origId = Binder.clearCallingIdentity();
8356        try {
8357            synchronized(this) {
8358                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8359                        "enterPictureInPictureMode", token, params);
8360
8361                // If the activity is already in picture in picture mode, then just return early
8362                if (isInPictureInPictureMode(r)) {
8363                    return true;
8364                }
8365
8366                // Activity supports picture-in-picture, now check that we can enter PiP at this
8367                // point, if it is
8368                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8369                        false /* beforeStopping */)) {
8370                    return false;
8371                }
8372
8373                final Runnable enterPipRunnable = () -> {
8374                    // Only update the saved args from the args that are set
8375                    r.pictureInPictureArgs.copyOnlySet(params);
8376                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8377                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8378                    // Adjust the source bounds by the insets for the transition down
8379                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8380                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8381                            "enterPictureInPictureMode");
8382                    final PinnedActivityStack stack = r.getStack();
8383                    stack.setPictureInPictureAspectRatio(aspectRatio);
8384                    stack.setPictureInPictureActions(actions);
8385
8386                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8387                            r.supportsEnterPipOnTaskSwitch);
8388                    logPictureInPictureArgs(params);
8389                };
8390
8391                if (isKeyguardLocked()) {
8392                    // If the keyguard is showing or occluded, then try and dismiss it before
8393                    // entering picture-in-picture (this will prompt the user to authenticate if the
8394                    // device is currently locked).
8395                    try {
8396                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8397                            @Override
8398                            public void onDismissError() throws RemoteException {
8399                                // Do nothing
8400                            }
8401
8402                            @Override
8403                            public void onDismissSucceeded() throws RemoteException {
8404                                mHandler.post(enterPipRunnable);
8405                            }
8406
8407                            @Override
8408                            public void onDismissCancelled() throws RemoteException {
8409                                // Do nothing
8410                            }
8411                        }, null /* message */);
8412                    } catch (RemoteException e) {
8413                        // Local call
8414                    }
8415                } else {
8416                    // Enter picture in picture immediately otherwise
8417                    enterPipRunnable.run();
8418                }
8419                return true;
8420            }
8421        } finally {
8422            Binder.restoreCallingIdentity(origId);
8423        }
8424    }
8425
8426    @Override
8427    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8428        final long origId = Binder.clearCallingIdentity();
8429        try {
8430            synchronized(this) {
8431                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8432                        "setPictureInPictureParams", token, params);
8433
8434                // Only update the saved args from the args that are set
8435                r.pictureInPictureArgs.copyOnlySet(params);
8436                if (r.inPinnedWindowingMode()) {
8437                    // If the activity is already in picture-in-picture, update the pinned stack now
8438                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8439                    // be used the next time the activity enters PiP
8440                    final PinnedActivityStack stack = r.getStack();
8441                    if (!stack.isAnimatingBoundsToFullscreen()) {
8442                        stack.setPictureInPictureAspectRatio(
8443                                r.pictureInPictureArgs.getAspectRatio());
8444                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8445                    }
8446                }
8447                logPictureInPictureArgs(params);
8448            }
8449        } finally {
8450            Binder.restoreCallingIdentity(origId);
8451        }
8452    }
8453
8454    @Override
8455    public int getMaxNumPictureInPictureActions(IBinder token) {
8456        // Currently, this is a static constant, but later, we may change this to be dependent on
8457        // the context of the activity
8458        return 3;
8459    }
8460
8461    private void logPictureInPictureArgs(PictureInPictureParams params) {
8462        if (params.hasSetActions()) {
8463            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8464                    params.getActions().size());
8465        }
8466        if (params.hasSetAspectRatio()) {
8467            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8468            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8469            MetricsLogger.action(lm);
8470        }
8471    }
8472
8473    /**
8474     * Checks the state of the system and the activity associated with the given {@param token} to
8475     * verify that picture-in-picture is supported for that activity.
8476     *
8477     * @return the activity record for the given {@param token} if all the checks pass.
8478     */
8479    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8480            IBinder token, PictureInPictureParams params) {
8481        if (!mSupportsPictureInPicture) {
8482            throw new IllegalStateException(caller
8483                    + ": Device doesn't support picture-in-picture mode.");
8484        }
8485
8486        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8487        if (r == null) {
8488            throw new IllegalStateException(caller
8489                    + ": Can't find activity for token=" + token);
8490        }
8491
8492        if (!r.supportsPictureInPicture()) {
8493            throw new IllegalStateException(caller
8494                    + ": Current activity does not support picture-in-picture.");
8495        }
8496
8497        if (params.hasSetAspectRatio()
8498                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8499                        params.getAspectRatio())) {
8500            final float minAspectRatio = mContext.getResources().getFloat(
8501                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8502            final float maxAspectRatio = mContext.getResources().getFloat(
8503                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8504            throw new IllegalArgumentException(String.format(caller
8505                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8506                            minAspectRatio, maxAspectRatio));
8507        }
8508
8509        // Truncate the number of actions if necessary
8510        params.truncateActions(getMaxNumPictureInPictureActions(token));
8511
8512        return r;
8513    }
8514
8515    // =========================================================
8516    // PROCESS INFO
8517    // =========================================================
8518
8519    static class ProcessInfoService extends IProcessInfoService.Stub {
8520        final ActivityManagerService mActivityManagerService;
8521        ProcessInfoService(ActivityManagerService activityManagerService) {
8522            mActivityManagerService = activityManagerService;
8523        }
8524
8525        @Override
8526        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8527            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8528                    /*in*/ pids, /*out*/ states, null);
8529        }
8530
8531        @Override
8532        public void getProcessStatesAndOomScoresFromPids(
8533                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8534            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8535                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8536        }
8537    }
8538
8539    /**
8540     * For each PID in the given input array, write the current process state
8541     * for that process into the states array, or -1 to indicate that no
8542     * process with the given PID exists. If scores array is provided, write
8543     * the oom score for the process into the scores array, with INVALID_ADJ
8544     * indicating the PID doesn't exist.
8545     */
8546    public void getProcessStatesAndOomScoresForPIDs(
8547            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8548        if (scores != null) {
8549            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8550                    "getProcessStatesAndOomScoresForPIDs()");
8551        }
8552
8553        if (pids == null) {
8554            throw new NullPointerException("pids");
8555        } else if (states == null) {
8556            throw new NullPointerException("states");
8557        } else if (pids.length != states.length) {
8558            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8559        } else if (scores != null && pids.length != scores.length) {
8560            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8561        }
8562
8563        synchronized (mPidsSelfLocked) {
8564            for (int i = 0; i < pids.length; i++) {
8565                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8566                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8567                        pr.curProcState;
8568                if (scores != null) {
8569                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8570                }
8571            }
8572        }
8573    }
8574
8575    // =========================================================
8576    // PERMISSIONS
8577    // =========================================================
8578
8579    static class PermissionController extends IPermissionController.Stub {
8580        ActivityManagerService mActivityManagerService;
8581        PermissionController(ActivityManagerService activityManagerService) {
8582            mActivityManagerService = activityManagerService;
8583        }
8584
8585        @Override
8586        public boolean checkPermission(String permission, int pid, int uid) {
8587            return mActivityManagerService.checkPermission(permission, pid,
8588                    uid) == PackageManager.PERMISSION_GRANTED;
8589        }
8590
8591        @Override
8592        public String[] getPackagesForUid(int uid) {
8593            return mActivityManagerService.mContext.getPackageManager()
8594                    .getPackagesForUid(uid);
8595        }
8596
8597        @Override
8598        public boolean isRuntimePermission(String permission) {
8599            try {
8600                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8601                        .getPermissionInfo(permission, 0);
8602                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8603                        == PermissionInfo.PROTECTION_DANGEROUS;
8604            } catch (NameNotFoundException nnfe) {
8605                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8606            }
8607            return false;
8608        }
8609    }
8610
8611    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8612        @Override
8613        public int checkComponentPermission(String permission, int pid, int uid,
8614                int owningUid, boolean exported) {
8615            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8616                    owningUid, exported);
8617        }
8618
8619        @Override
8620        public Object getAMSLock() {
8621            return ActivityManagerService.this;
8622        }
8623    }
8624
8625    int checkComponentPermission(String permission, int pid, int uid,
8626            int owningUid, boolean exported) {
8627        if (pid == MY_PID) {
8628            return PackageManager.PERMISSION_GRANTED;
8629        }
8630        return ActivityManager.checkComponentPermission(permission, uid,
8631                owningUid, exported);
8632    }
8633
8634    /**
8635     * As the only public entry point for permissions checking, this method
8636     * can enforce the semantic that requesting a check on a null global
8637     * permission is automatically denied.  (Internally a null permission
8638     * string is used when calling {@link #checkComponentPermission} in cases
8639     * when only uid-based security is needed.)
8640     *
8641     * This can be called with or without the global lock held.
8642     */
8643    @Override
8644    public int checkPermission(String permission, int pid, int uid) {
8645        if (permission == null) {
8646            return PackageManager.PERMISSION_DENIED;
8647        }
8648        return checkComponentPermission(permission, pid, uid, -1, true);
8649    }
8650
8651    @Override
8652    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8653        if (permission == null) {
8654            return PackageManager.PERMISSION_DENIED;
8655        }
8656
8657        // We might be performing an operation on behalf of an indirect binder
8658        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8659        // client identity accordingly before proceeding.
8660        Identity tlsIdentity = sCallerIdentity.get();
8661        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8662            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8663                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8664            uid = tlsIdentity.uid;
8665            pid = tlsIdentity.pid;
8666        }
8667
8668        return checkComponentPermission(permission, pid, uid, -1, true);
8669    }
8670
8671    /**
8672     * Binder IPC calls go through the public entry point.
8673     * This can be called with or without the global lock held.
8674     */
8675    int checkCallingPermission(String permission) {
8676        return checkPermission(permission,
8677                Binder.getCallingPid(),
8678                UserHandle.getAppId(Binder.getCallingUid()));
8679    }
8680
8681    /**
8682     * This can be called with or without the global lock held.
8683     */
8684    void enforceCallingPermission(String permission, String func) {
8685        if (checkCallingPermission(permission)
8686                == PackageManager.PERMISSION_GRANTED) {
8687            return;
8688        }
8689
8690        String msg = "Permission Denial: " + func + " from pid="
8691                + Binder.getCallingPid()
8692                + ", uid=" + Binder.getCallingUid()
8693                + " requires " + permission;
8694        Slog.w(TAG, msg);
8695        throw new SecurityException(msg);
8696    }
8697
8698    /**
8699     * This can be called with or without the global lock held.
8700     */
8701    void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
8702        if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
8703            enforceCallingPermission(permission, func);
8704        }
8705    }
8706
8707    /**
8708     * Determine if UID is holding permissions required to access {@link Uri} in
8709     * the given {@link ProviderInfo}. Final permission checking is always done
8710     * in {@link ContentProvider}.
8711     */
8712    private final boolean checkHoldingPermissionsLocked(
8713            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8714        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8715                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8716        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8717            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8718                    != PERMISSION_GRANTED) {
8719                return false;
8720            }
8721        }
8722        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8723    }
8724
8725    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8726            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8727        if (pi.applicationInfo.uid == uid) {
8728            return true;
8729        } else if (!pi.exported) {
8730            return false;
8731        }
8732
8733        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8734        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8735        try {
8736            // check if target holds top-level <provider> permissions
8737            if (!readMet && pi.readPermission != null && considerUidPermissions
8738                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8739                readMet = true;
8740            }
8741            if (!writeMet && pi.writePermission != null && considerUidPermissions
8742                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8743                writeMet = true;
8744            }
8745
8746            // track if unprotected read/write is allowed; any denied
8747            // <path-permission> below removes this ability
8748            boolean allowDefaultRead = pi.readPermission == null;
8749            boolean allowDefaultWrite = pi.writePermission == null;
8750
8751            // check if target holds any <path-permission> that match uri
8752            final PathPermission[] pps = pi.pathPermissions;
8753            if (pps != null) {
8754                final String path = grantUri.uri.getPath();
8755                int i = pps.length;
8756                while (i > 0 && (!readMet || !writeMet)) {
8757                    i--;
8758                    PathPermission pp = pps[i];
8759                    if (pp.match(path)) {
8760                        if (!readMet) {
8761                            final String pprperm = pp.getReadPermission();
8762                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8763                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8764                                    + ": match=" + pp.match(path)
8765                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8766                            if (pprperm != null) {
8767                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8768                                        == PERMISSION_GRANTED) {
8769                                    readMet = true;
8770                                } else {
8771                                    allowDefaultRead = false;
8772                                }
8773                            }
8774                        }
8775                        if (!writeMet) {
8776                            final String ppwperm = pp.getWritePermission();
8777                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8778                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8779                                    + ": match=" + pp.match(path)
8780                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8781                            if (ppwperm != null) {
8782                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8783                                        == PERMISSION_GRANTED) {
8784                                    writeMet = true;
8785                                } else {
8786                                    allowDefaultWrite = false;
8787                                }
8788                            }
8789                        }
8790                    }
8791                }
8792            }
8793
8794            // grant unprotected <provider> read/write, if not blocked by
8795            // <path-permission> above
8796            if (allowDefaultRead) readMet = true;
8797            if (allowDefaultWrite) writeMet = true;
8798
8799        } catch (RemoteException e) {
8800            return false;
8801        }
8802
8803        return readMet && writeMet;
8804    }
8805
8806    public boolean isAppStartModeDisabled(int uid, String packageName) {
8807        synchronized (this) {
8808            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8809                    == ActivityManager.APP_START_MODE_DISABLED;
8810        }
8811    }
8812
8813    // Unified app-op and target sdk check
8814    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8815        // Apps that target O+ are always subject to background check
8816        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8817            if (DEBUG_BACKGROUND_CHECK) {
8818                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8819            }
8820            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8821        }
8822        // ...and legacy apps get an AppOp check
8823        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8824                uid, packageName);
8825        if (DEBUG_BACKGROUND_CHECK) {
8826            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8827        }
8828        switch (appop) {
8829            case AppOpsManager.MODE_ALLOWED:
8830                // If force-background-check is enabled, restrict all apps that aren't whitelisted.
8831                if (mForceBackgroundCheck &&
8832                        UserHandle.isApp(uid) &&
8833                        !isOnDeviceIdleWhitelistLocked(uid)) {
8834                    if (DEBUG_BACKGROUND_CHECK) {
8835                        Slog.i(TAG, "Force background check: " +
8836                                uid + "/" + packageName + " restricted");
8837                    }
8838                    return ActivityManager.APP_START_MODE_DELAYED;
8839                }
8840                return ActivityManager.APP_START_MODE_NORMAL;
8841            case AppOpsManager.MODE_IGNORED:
8842                return ActivityManager.APP_START_MODE_DELAYED;
8843            default:
8844                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8845        }
8846    }
8847
8848    // Service launch is available to apps with run-in-background exemptions but
8849    // some other background operations are not.  If we're doing a check
8850    // of service-launch policy, allow those callers to proceed unrestricted.
8851    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8852        // Persistent app?
8853        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8854            if (DEBUG_BACKGROUND_CHECK) {
8855                Slog.i(TAG, "App " + uid + "/" + packageName
8856                        + " is persistent; not restricted in background");
8857            }
8858            return ActivityManager.APP_START_MODE_NORMAL;
8859        }
8860
8861        // Non-persistent but background whitelisted?
8862        if (uidOnBackgroundWhitelist(uid)) {
8863            if (DEBUG_BACKGROUND_CHECK) {
8864                Slog.i(TAG, "App " + uid + "/" + packageName
8865                        + " on background whitelist; not restricted in background");
8866            }
8867            return ActivityManager.APP_START_MODE_NORMAL;
8868        }
8869
8870        // Is this app on the battery whitelist?
8871        if (isOnDeviceIdleWhitelistLocked(uid)) {
8872            if (DEBUG_BACKGROUND_CHECK) {
8873                Slog.i(TAG, "App " + uid + "/" + packageName
8874                        + " on idle whitelist; not restricted in background");
8875            }
8876            return ActivityManager.APP_START_MODE_NORMAL;
8877        }
8878
8879        // None of the service-policy criteria apply, so we apply the common criteria
8880        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8881    }
8882
8883    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8884            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8885        UidRecord uidRec = mActiveUids.get(uid);
8886        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8887                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8888                + (uidRec != null ? uidRec.idle : false));
8889        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8890            boolean ephemeral;
8891            if (uidRec == null) {
8892                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8893                        UserHandle.getUserId(uid), packageName);
8894            } else {
8895                ephemeral = uidRec.ephemeral;
8896            }
8897
8898            if (ephemeral) {
8899                // We are hard-core about ephemeral apps not running in the background.
8900                return ActivityManager.APP_START_MODE_DISABLED;
8901            } else {
8902                if (disabledOnly) {
8903                    // The caller is only interested in whether app starts are completely
8904                    // disabled for the given package (that is, it is an instant app).  So
8905                    // we don't need to go further, which is all just seeing if we should
8906                    // apply a "delayed" mode for a regular app.
8907                    return ActivityManager.APP_START_MODE_NORMAL;
8908                }
8909                final int startMode = (alwaysRestrict)
8910                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8911                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8912                                packageTargetSdk);
8913                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8914                        + " pkg=" + packageName + " startMode=" + startMode
8915                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8916                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8917                    // This is an old app that has been forced into a "compatible as possible"
8918                    // mode of background check.  To increase compatibility, we will allow other
8919                    // foreground apps to cause its services to start.
8920                    if (callingPid >= 0) {
8921                        ProcessRecord proc;
8922                        synchronized (mPidsSelfLocked) {
8923                            proc = mPidsSelfLocked.get(callingPid);
8924                        }
8925                        if (proc != null &&
8926                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
8927                            // Whoever is instigating this is in the foreground, so we will allow it
8928                            // to go through.
8929                            return ActivityManager.APP_START_MODE_NORMAL;
8930                        }
8931                    }
8932                }
8933                return startMode;
8934            }
8935        }
8936        return ActivityManager.APP_START_MODE_NORMAL;
8937    }
8938
8939    /**
8940     * @return whether a UID is in the system, user or temp doze whitelist.
8941     */
8942    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8943        final int appId = UserHandle.getAppId(uid);
8944        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8945                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8946                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8947    }
8948
8949    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8950        ProviderInfo pi = null;
8951        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8952        if (cpr != null) {
8953            pi = cpr.info;
8954        } else {
8955            try {
8956                pi = AppGlobals.getPackageManager().resolveContentProvider(
8957                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8958                        userHandle);
8959            } catch (RemoteException ex) {
8960            }
8961        }
8962        return pi;
8963    }
8964
8965    void grantEphemeralAccessLocked(int userId, Intent intent,
8966            int targetAppId, int ephemeralAppId) {
8967        getPackageManagerInternalLocked().
8968                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8969    }
8970
8971    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8972        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8973        if (targetUris != null) {
8974            return targetUris.get(grantUri);
8975        }
8976        return null;
8977    }
8978
8979    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8980            String targetPkg, int targetUid, GrantUri grantUri) {
8981        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8982        if (targetUris == null) {
8983            targetUris = Maps.newArrayMap();
8984            mGrantedUriPermissions.put(targetUid, targetUris);
8985        }
8986
8987        UriPermission perm = targetUris.get(grantUri);
8988        if (perm == null) {
8989            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8990            targetUris.put(grantUri, perm);
8991        }
8992
8993        return perm;
8994    }
8995
8996    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8997            final int modeFlags) {
8998        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8999        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
9000                : UriPermission.STRENGTH_OWNED;
9001
9002        // Root gets to do everything.
9003        if (uid == 0) {
9004            return true;
9005        }
9006
9007        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9008        if (perms == null) return false;
9009
9010        // First look for exact match
9011        final UriPermission exactPerm = perms.get(grantUri);
9012        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
9013            return true;
9014        }
9015
9016        // No exact match, look for prefixes
9017        final int N = perms.size();
9018        for (int i = 0; i < N; i++) {
9019            final UriPermission perm = perms.valueAt(i);
9020            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
9021                    && perm.getStrength(modeFlags) >= minStrength) {
9022                return true;
9023            }
9024        }
9025
9026        return false;
9027    }
9028
9029    /**
9030     * @param uri This uri must NOT contain an embedded userId.
9031     * @param userId The userId in which the uri is to be resolved.
9032     */
9033    @Override
9034    public int checkUriPermission(Uri uri, int pid, int uid,
9035            final int modeFlags, int userId, IBinder callerToken) {
9036        enforceNotIsolatedCaller("checkUriPermission");
9037
9038        // Another redirected-binder-call permissions check as in
9039        // {@link checkPermissionWithToken}.
9040        Identity tlsIdentity = sCallerIdentity.get();
9041        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9042            uid = tlsIdentity.uid;
9043            pid = tlsIdentity.pid;
9044        }
9045
9046        // Our own process gets to do everything.
9047        if (pid == MY_PID) {
9048            return PackageManager.PERMISSION_GRANTED;
9049        }
9050        synchronized (this) {
9051            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
9052                    ? PackageManager.PERMISSION_GRANTED
9053                    : PackageManager.PERMISSION_DENIED;
9054        }
9055    }
9056
9057    /**
9058     * Check if the targetPkg can be granted permission to access uri by
9059     * the callingUid using the given modeFlags.  Throws a security exception
9060     * if callingUid is not allowed to do this.  Returns the uid of the target
9061     * if the URI permission grant should be performed; returns -1 if it is not
9062     * needed (for example targetPkg already has permission to access the URI).
9063     * If you already know the uid of the target, you can supply it in
9064     * lastTargetUid else set that to -1.
9065     */
9066    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9067            final int modeFlags, int lastTargetUid) {
9068        if (!Intent.isAccessUriMode(modeFlags)) {
9069            return -1;
9070        }
9071
9072        if (targetPkg != null) {
9073            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9074                    "Checking grant " + targetPkg + " permission to " + grantUri);
9075        }
9076
9077        final IPackageManager pm = AppGlobals.getPackageManager();
9078
9079        // If this is not a content: uri, we can't do anything with it.
9080        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
9081            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9082                    "Can't grant URI permission for non-content URI: " + grantUri);
9083            return -1;
9084        }
9085
9086        // Bail early if system is trying to hand out permissions directly; it
9087        // must always grant permissions on behalf of someone explicit.
9088        final int callingAppId = UserHandle.getAppId(callingUid);
9089        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
9090            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
9091                // Exempted authority for
9092                // 1. cropping user photos and sharing a generated license html
9093                //    file in Settings app
9094                // 2. sharing a generated license html file in TvSettings app
9095            } else {
9096                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
9097                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
9098                return -1;
9099            }
9100        }
9101
9102        final String authority = grantUri.uri.getAuthority();
9103        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9104                MATCH_DEBUG_TRIAGED_MISSING);
9105        if (pi == null) {
9106            Slog.w(TAG, "No content provider found for permission check: " +
9107                    grantUri.uri.toSafeString());
9108            return -1;
9109        }
9110
9111        int targetUid = lastTargetUid;
9112        if (targetUid < 0 && targetPkg != null) {
9113            try {
9114                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9115                        UserHandle.getUserId(callingUid));
9116                if (targetUid < 0) {
9117                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9118                            "Can't grant URI permission no uid for: " + targetPkg);
9119                    return -1;
9120                }
9121            } catch (RemoteException ex) {
9122                return -1;
9123            }
9124        }
9125
9126        // If we're extending a persistable grant, then we always need to create
9127        // the grant data structure so that take/release APIs work
9128        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
9129            return targetUid;
9130        }
9131
9132        if (targetUid >= 0) {
9133            // First...  does the target actually need this permission?
9134            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
9135                // No need to grant the target this permission.
9136                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9137                        "Target " + targetPkg + " already has full permission to " + grantUri);
9138                return -1;
9139            }
9140        } else {
9141            // First...  there is no target package, so can anyone access it?
9142            boolean allowed = pi.exported;
9143            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9144                if (pi.readPermission != null) {
9145                    allowed = false;
9146                }
9147            }
9148            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9149                if (pi.writePermission != null) {
9150                    allowed = false;
9151                }
9152            }
9153            if (allowed) {
9154                return -1;
9155            }
9156        }
9157
9158        /* There is a special cross user grant if:
9159         * - The target is on another user.
9160         * - Apps on the current user can access the uri without any uid permissions.
9161         * In this case, we grant a uri permission, even if the ContentProvider does not normally
9162         * grant uri permissions.
9163         */
9164        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
9165                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
9166                modeFlags, false /*without considering the uid permissions*/);
9167
9168        // Second...  is the provider allowing granting of URI permissions?
9169        if (!specialCrossUserGrant) {
9170            if (!pi.grantUriPermissions) {
9171                throw new SecurityException("Provider " + pi.packageName
9172                        + "/" + pi.name
9173                        + " does not allow granting of Uri permissions (uri "
9174                        + grantUri + ")");
9175            }
9176            if (pi.uriPermissionPatterns != null) {
9177                final int N = pi.uriPermissionPatterns.length;
9178                boolean allowed = false;
9179                for (int i=0; i<N; i++) {
9180                    if (pi.uriPermissionPatterns[i] != null
9181                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
9182                        allowed = true;
9183                        break;
9184                    }
9185                }
9186                if (!allowed) {
9187                    throw new SecurityException("Provider " + pi.packageName
9188                            + "/" + pi.name
9189                            + " does not allow granting of permission to path of Uri "
9190                            + grantUri);
9191                }
9192            }
9193        }
9194
9195        // Third...  does the caller itself have permission to access
9196        // this uri?
9197        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9198            // Require they hold a strong enough Uri permission
9199            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
9200                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
9201                    throw new SecurityException(
9202                            "UID " + callingUid + " does not have permission to " + grantUri
9203                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
9204                                    + "or related APIs");
9205                } else {
9206                    throw new SecurityException(
9207                            "UID " + callingUid + " does not have permission to " + grantUri);
9208                }
9209            }
9210        }
9211        return targetUid;
9212    }
9213
9214    /**
9215     * @param uri This uri must NOT contain an embedded userId.
9216     * @param userId The userId in which the uri is to be resolved.
9217     */
9218    @Override
9219    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
9220            final int modeFlags, int userId) {
9221        enforceNotIsolatedCaller("checkGrantUriPermission");
9222        synchronized(this) {
9223            return checkGrantUriPermissionLocked(callingUid, targetPkg,
9224                    new GrantUri(userId, uri, false), modeFlags, -1);
9225        }
9226    }
9227
9228    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
9229            final int modeFlags, UriPermissionOwner owner) {
9230        if (!Intent.isAccessUriMode(modeFlags)) {
9231            return;
9232        }
9233
9234        // So here we are: the caller has the assumed permission
9235        // to the uri, and the target doesn't.  Let's now give this to
9236        // the target.
9237
9238        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9239                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
9240
9241        final String authority = grantUri.uri.getAuthority();
9242        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9243                MATCH_DEBUG_TRIAGED_MISSING);
9244        if (pi == null) {
9245            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
9246            return;
9247        }
9248
9249        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
9250            grantUri.prefix = true;
9251        }
9252        final UriPermission perm = findOrCreateUriPermissionLocked(
9253                pi.packageName, targetPkg, targetUid, grantUri);
9254        perm.grantModes(modeFlags, owner);
9255    }
9256
9257    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9258            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9259        if (targetPkg == null) {
9260            throw new NullPointerException("targetPkg");
9261        }
9262        int targetUid;
9263        final IPackageManager pm = AppGlobals.getPackageManager();
9264        try {
9265            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9266        } catch (RemoteException ex) {
9267            return;
9268        }
9269
9270        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9271                targetUid);
9272        if (targetUid < 0) {
9273            return;
9274        }
9275
9276        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9277                owner);
9278    }
9279
9280    static class NeededUriGrants extends ArrayList<GrantUri> {
9281        final String targetPkg;
9282        final int targetUid;
9283        final int flags;
9284
9285        NeededUriGrants(String targetPkg, int targetUid, int flags) {
9286            this.targetPkg = targetPkg;
9287            this.targetUid = targetUid;
9288            this.flags = flags;
9289        }
9290
9291        void writeToProto(ProtoOutputStream proto, long fieldId) {
9292            long token = proto.start(fieldId);
9293            proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
9294            proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
9295            proto.write(NeededUriGrantsProto.FLAGS, flags);
9296
9297            final int N = this.size();
9298            for (int i=0; i<N; i++) {
9299                this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
9300            }
9301            proto.end(token);
9302        }
9303    }
9304
9305    /**
9306     * Like checkGrantUriPermissionLocked, but takes an Intent.
9307     */
9308    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9309            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9310        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9311                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9312                + " clip=" + (intent != null ? intent.getClipData() : null)
9313                + " from " + intent + "; flags=0x"
9314                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9315
9316        if (targetPkg == null) {
9317            throw new NullPointerException("targetPkg");
9318        }
9319
9320        if (intent == null) {
9321            return null;
9322        }
9323        Uri data = intent.getData();
9324        ClipData clip = intent.getClipData();
9325        if (data == null && clip == null) {
9326            return null;
9327        }
9328        // Default userId for uris in the intent (if they don't specify it themselves)
9329        int contentUserHint = intent.getContentUserHint();
9330        if (contentUserHint == UserHandle.USER_CURRENT) {
9331            contentUserHint = UserHandle.getUserId(callingUid);
9332        }
9333        final IPackageManager pm = AppGlobals.getPackageManager();
9334        int targetUid;
9335        if (needed != null) {
9336            targetUid = needed.targetUid;
9337        } else {
9338            try {
9339                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9340                        targetUserId);
9341            } catch (RemoteException ex) {
9342                return null;
9343            }
9344            if (targetUid < 0) {
9345                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9346                        "Can't grant URI permission no uid for: " + targetPkg
9347                        + " on user " + targetUserId);
9348                return null;
9349            }
9350        }
9351        if (data != null) {
9352            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9353            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9354                    targetUid);
9355            if (targetUid > 0) {
9356                if (needed == null) {
9357                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
9358                }
9359                needed.add(grantUri);
9360            }
9361        }
9362        if (clip != null) {
9363            for (int i=0; i<clip.getItemCount(); i++) {
9364                Uri uri = clip.getItemAt(i).getUri();
9365                if (uri != null) {
9366                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9367                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9368                            targetUid);
9369                    if (targetUid > 0) {
9370                        if (needed == null) {
9371                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
9372                        }
9373                        needed.add(grantUri);
9374                    }
9375                } else {
9376                    Intent clipIntent = clip.getItemAt(i).getIntent();
9377                    if (clipIntent != null) {
9378                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9379                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9380                        if (newNeeded != null) {
9381                            needed = newNeeded;
9382                        }
9383                    }
9384                }
9385            }
9386        }
9387
9388        return needed;
9389    }
9390
9391    /**
9392     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9393     */
9394    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9395            UriPermissionOwner owner) {
9396        if (needed != null) {
9397            for (int i=0; i<needed.size(); i++) {
9398                GrantUri grantUri = needed.get(i);
9399                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9400                        grantUri, needed.flags, owner);
9401            }
9402        }
9403    }
9404
9405    void grantUriPermissionFromIntentLocked(int callingUid,
9406            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9407        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9408                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9409        if (needed == null) {
9410            return;
9411        }
9412
9413        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9414    }
9415
9416    /**
9417     * @param uri This uri must NOT contain an embedded userId.
9418     * @param userId The userId in which the uri is to be resolved.
9419     */
9420    @Override
9421    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9422            final int modeFlags, int userId) {
9423        enforceNotIsolatedCaller("grantUriPermission");
9424        GrantUri grantUri = new GrantUri(userId, uri, false);
9425        synchronized(this) {
9426            final ProcessRecord r = getRecordForAppLocked(caller);
9427            if (r == null) {
9428                throw new SecurityException("Unable to find app for caller "
9429                        + caller
9430                        + " when granting permission to uri " + grantUri);
9431            }
9432            if (targetPkg == null) {
9433                throw new IllegalArgumentException("null target");
9434            }
9435            if (grantUri == null) {
9436                throw new IllegalArgumentException("null uri");
9437            }
9438
9439            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9440                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9441                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9442                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9443
9444            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9445                    UserHandle.getUserId(r.uid));
9446        }
9447    }
9448
9449    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9450        if (perm.modeFlags == 0) {
9451            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9452                    perm.targetUid);
9453            if (perms != null) {
9454                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9455                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9456
9457                perms.remove(perm.uri);
9458                if (perms.isEmpty()) {
9459                    mGrantedUriPermissions.remove(perm.targetUid);
9460                }
9461            }
9462        }
9463    }
9464
9465    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9466            final int modeFlags) {
9467        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9468                "Revoking all granted permissions to " + grantUri);
9469
9470        final IPackageManager pm = AppGlobals.getPackageManager();
9471        final String authority = grantUri.uri.getAuthority();
9472        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9473                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9474        if (pi == null) {
9475            Slog.w(TAG, "No content provider found for permission revoke: "
9476                    + grantUri.toSafeString());
9477            return;
9478        }
9479
9480        // Does the caller have this permission on the URI?
9481        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9482            // If they don't have direct access to the URI, then revoke any
9483            // ownerless URI permissions that have been granted to them.
9484            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9485            if (perms != null) {
9486                boolean persistChanged = false;
9487                for (int i = perms.size()-1; i >= 0; i--) {
9488                    final UriPermission perm = perms.valueAt(i);
9489                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9490                        continue;
9491                    }
9492                    if (perm.uri.sourceUserId == grantUri.sourceUserId
9493                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9494                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9495                                "Revoking non-owned " + perm.targetUid
9496                                + " permission to " + perm.uri);
9497                        persistChanged |= perm.revokeModes(
9498                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9499                        if (perm.modeFlags == 0) {
9500                            perms.removeAt(i);
9501                        }
9502                    }
9503                }
9504                if (perms.isEmpty()) {
9505                    mGrantedUriPermissions.remove(callingUid);
9506                }
9507                if (persistChanged) {
9508                    schedulePersistUriGrants();
9509                }
9510            }
9511            return;
9512        }
9513
9514        boolean persistChanged = false;
9515
9516        // Go through all of the permissions and remove any that match.
9517        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9518            final int targetUid = mGrantedUriPermissions.keyAt(i);
9519            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9520
9521            for (int j = perms.size()-1; j >= 0; j--) {
9522                final UriPermission perm = perms.valueAt(j);
9523                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9524                    continue;
9525                }
9526                if (perm.uri.sourceUserId == grantUri.sourceUserId
9527                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9528                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9529                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9530                    persistChanged |= perm.revokeModes(
9531                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9532                            targetPackage == null);
9533                    if (perm.modeFlags == 0) {
9534                        perms.removeAt(j);
9535                    }
9536                }
9537            }
9538
9539            if (perms.isEmpty()) {
9540                mGrantedUriPermissions.removeAt(i);
9541            }
9542        }
9543
9544        if (persistChanged) {
9545            schedulePersistUriGrants();
9546        }
9547    }
9548
9549    /**
9550     * @param uri This uri must NOT contain an embedded userId.
9551     * @param userId The userId in which the uri is to be resolved.
9552     */
9553    @Override
9554    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9555            final int modeFlags, int userId) {
9556        enforceNotIsolatedCaller("revokeUriPermission");
9557        synchronized(this) {
9558            final ProcessRecord r = getRecordForAppLocked(caller);
9559            if (r == null) {
9560                throw new SecurityException("Unable to find app for caller "
9561                        + caller
9562                        + " when revoking permission to uri " + uri);
9563            }
9564            if (uri == null) {
9565                Slog.w(TAG, "revokeUriPermission: null uri");
9566                return;
9567            }
9568
9569            if (!Intent.isAccessUriMode(modeFlags)) {
9570                return;
9571            }
9572
9573            final String authority = uri.getAuthority();
9574            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9575                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9576            if (pi == null) {
9577                Slog.w(TAG, "No content provider found for permission revoke: "
9578                        + uri.toSafeString());
9579                return;
9580            }
9581
9582            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9583                    modeFlags);
9584        }
9585    }
9586
9587    /**
9588     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9589     * given package.
9590     *
9591     * @param packageName Package name to match, or {@code null} to apply to all
9592     *            packages.
9593     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9594     *            to all users.
9595     * @param persistable If persistable grants should be removed.
9596     */
9597    private void removeUriPermissionsForPackageLocked(
9598            String packageName, int userHandle, boolean persistable) {
9599        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9600            throw new IllegalArgumentException("Must narrow by either package or user");
9601        }
9602
9603        boolean persistChanged = false;
9604
9605        int N = mGrantedUriPermissions.size();
9606        for (int i = 0; i < N; i++) {
9607            final int targetUid = mGrantedUriPermissions.keyAt(i);
9608            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9609
9610            // Only inspect grants matching user
9611            if (userHandle == UserHandle.USER_ALL
9612                    || userHandle == UserHandle.getUserId(targetUid)) {
9613                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9614                    final UriPermission perm = it.next();
9615
9616                    // Only inspect grants matching package
9617                    if (packageName == null || perm.sourcePkg.equals(packageName)
9618                            || perm.targetPkg.equals(packageName)) {
9619                        // Hacky solution as part of fixing a security bug; ignore
9620                        // grants associated with DownloadManager so we don't have
9621                        // to immediately launch it to regrant the permissions
9622                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9623                                && !persistable) continue;
9624
9625                        persistChanged |= perm.revokeModes(persistable
9626                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9627
9628                        // Only remove when no modes remain; any persisted grants
9629                        // will keep this alive.
9630                        if (perm.modeFlags == 0) {
9631                            it.remove();
9632                        }
9633                    }
9634                }
9635
9636                if (perms.isEmpty()) {
9637                    mGrantedUriPermissions.remove(targetUid);
9638                    N--;
9639                    i--;
9640                }
9641            }
9642        }
9643
9644        if (persistChanged) {
9645            schedulePersistUriGrants();
9646        }
9647    }
9648
9649    @Override
9650    public IBinder newUriPermissionOwner(String name) {
9651        enforceNotIsolatedCaller("newUriPermissionOwner");
9652        synchronized(this) {
9653            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9654            return owner.getExternalTokenLocked();
9655        }
9656    }
9657
9658    @Override
9659    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9660        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9661        synchronized(this) {
9662            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9663            if (r == null) {
9664                throw new IllegalArgumentException("Activity does not exist; token="
9665                        + activityToken);
9666            }
9667            return r.getUriPermissionsLocked().getExternalTokenLocked();
9668        }
9669    }
9670    /**
9671     * @param uri This uri must NOT contain an embedded userId.
9672     * @param sourceUserId The userId in which the uri is to be resolved.
9673     * @param targetUserId The userId of the app that receives the grant.
9674     */
9675    @Override
9676    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9677            final int modeFlags, int sourceUserId, int targetUserId) {
9678        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9679                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9680                "grantUriPermissionFromOwner", null);
9681        synchronized(this) {
9682            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9683            if (owner == null) {
9684                throw new IllegalArgumentException("Unknown owner: " + token);
9685            }
9686            if (fromUid != Binder.getCallingUid()) {
9687                if (Binder.getCallingUid() != myUid()) {
9688                    // Only system code can grant URI permissions on behalf
9689                    // of other users.
9690                    throw new SecurityException("nice try");
9691                }
9692            }
9693            if (targetPkg == null) {
9694                throw new IllegalArgumentException("null target");
9695            }
9696            if (uri == null) {
9697                throw new IllegalArgumentException("null uri");
9698            }
9699
9700            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9701                    modeFlags, owner, targetUserId);
9702        }
9703    }
9704
9705    /**
9706     * @param uri This uri must NOT contain an embedded userId.
9707     * @param userId The userId in which the uri is to be resolved.
9708     */
9709    @Override
9710    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9711        synchronized(this) {
9712            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9713            if (owner == null) {
9714                throw new IllegalArgumentException("Unknown owner: " + token);
9715            }
9716
9717            if (uri == null) {
9718                owner.removeUriPermissionsLocked(mode);
9719            } else {
9720                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9721                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9722            }
9723        }
9724    }
9725
9726    private void schedulePersistUriGrants() {
9727        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9728            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9729                    10 * DateUtils.SECOND_IN_MILLIS);
9730        }
9731    }
9732
9733    private void writeGrantedUriPermissions() {
9734        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9735
9736        // Snapshot permissions so we can persist without lock
9737        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9738        synchronized (this) {
9739            final int size = mGrantedUriPermissions.size();
9740            for (int i = 0; i < size; i++) {
9741                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9742                for (UriPermission perm : perms.values()) {
9743                    if (perm.persistedModeFlags != 0) {
9744                        persist.add(perm.snapshot());
9745                    }
9746                }
9747            }
9748        }
9749
9750        FileOutputStream fos = null;
9751        try {
9752            fos = mGrantFile.startWrite();
9753
9754            XmlSerializer out = new FastXmlSerializer();
9755            out.setOutput(fos, StandardCharsets.UTF_8.name());
9756            out.startDocument(null, true);
9757            out.startTag(null, TAG_URI_GRANTS);
9758            for (UriPermission.Snapshot perm : persist) {
9759                out.startTag(null, TAG_URI_GRANT);
9760                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9761                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9762                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9763                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9764                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9765                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9766                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9767                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9768                out.endTag(null, TAG_URI_GRANT);
9769            }
9770            out.endTag(null, TAG_URI_GRANTS);
9771            out.endDocument();
9772
9773            mGrantFile.finishWrite(fos);
9774        } catch (IOException e) {
9775            if (fos != null) {
9776                mGrantFile.failWrite(fos);
9777            }
9778        }
9779    }
9780
9781    private void readGrantedUriPermissionsLocked() {
9782        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9783
9784        final long now = System.currentTimeMillis();
9785
9786        FileInputStream fis = null;
9787        try {
9788            fis = mGrantFile.openRead();
9789            final XmlPullParser in = Xml.newPullParser();
9790            in.setInput(fis, StandardCharsets.UTF_8.name());
9791
9792            int type;
9793            while ((type = in.next()) != END_DOCUMENT) {
9794                final String tag = in.getName();
9795                if (type == START_TAG) {
9796                    if (TAG_URI_GRANT.equals(tag)) {
9797                        final int sourceUserId;
9798                        final int targetUserId;
9799                        final int userHandle = readIntAttribute(in,
9800                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9801                        if (userHandle != UserHandle.USER_NULL) {
9802                            // For backwards compatibility.
9803                            sourceUserId = userHandle;
9804                            targetUserId = userHandle;
9805                        } else {
9806                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9807                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9808                        }
9809                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9810                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9811                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9812                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9813                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9814                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9815
9816                        // Sanity check that provider still belongs to source package
9817                        // Both direct boot aware and unaware packages are fine as we
9818                        // will do filtering at query time to avoid multiple parsing.
9819                        final ProviderInfo pi = getProviderInfoLocked(
9820                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9821                                        | MATCH_DIRECT_BOOT_UNAWARE);
9822                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9823                            int targetUid = -1;
9824                            try {
9825                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9826                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9827                            } catch (RemoteException e) {
9828                            }
9829                            if (targetUid != -1) {
9830                                final UriPermission perm = findOrCreateUriPermissionLocked(
9831                                        sourcePkg, targetPkg, targetUid,
9832                                        new GrantUri(sourceUserId, uri, prefix));
9833                                perm.initPersistedModes(modeFlags, createdTime);
9834                            }
9835                        } else {
9836                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9837                                    + " but instead found " + pi);
9838                        }
9839                    }
9840                }
9841            }
9842        } catch (FileNotFoundException e) {
9843            // Missing grants is okay
9844        } catch (IOException e) {
9845            Slog.wtf(TAG, "Failed reading Uri grants", e);
9846        } catch (XmlPullParserException e) {
9847            Slog.wtf(TAG, "Failed reading Uri grants", e);
9848        } finally {
9849            IoUtils.closeQuietly(fis);
9850        }
9851    }
9852
9853    /**
9854     * @param uri This uri must NOT contain an embedded userId.
9855     * @param userId The userId in which the uri is to be resolved.
9856     */
9857    @Override
9858    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9859        enforceNotIsolatedCaller("takePersistableUriPermission");
9860
9861        Preconditions.checkFlagsArgument(modeFlags,
9862                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9863
9864        synchronized (this) {
9865            final int callingUid = Binder.getCallingUid();
9866            boolean persistChanged = false;
9867            GrantUri grantUri = new GrantUri(userId, uri, false);
9868
9869            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9870                    new GrantUri(userId, uri, false));
9871            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9872                    new GrantUri(userId, uri, true));
9873
9874            final boolean exactValid = (exactPerm != null)
9875                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9876            final boolean prefixValid = (prefixPerm != null)
9877                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9878
9879            if (!(exactValid || prefixValid)) {
9880                throw new SecurityException("No persistable permission grants found for UID "
9881                        + callingUid + " and Uri " + grantUri.toSafeString());
9882            }
9883
9884            if (exactValid) {
9885                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9886            }
9887            if (prefixValid) {
9888                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9889            }
9890
9891            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9892
9893            if (persistChanged) {
9894                schedulePersistUriGrants();
9895            }
9896        }
9897    }
9898
9899    /**
9900     * @param uri This uri must NOT contain an embedded userId.
9901     * @param userId The userId in which the uri is to be resolved.
9902     */
9903    @Override
9904    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9905        enforceNotIsolatedCaller("releasePersistableUriPermission");
9906
9907        Preconditions.checkFlagsArgument(modeFlags,
9908                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9909
9910        synchronized (this) {
9911            final int callingUid = Binder.getCallingUid();
9912            boolean persistChanged = false;
9913
9914            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9915                    new GrantUri(userId, uri, false));
9916            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9917                    new GrantUri(userId, uri, true));
9918            if (exactPerm == null && prefixPerm == null) {
9919                throw new SecurityException("No permission grants found for UID " + callingUid
9920                        + " and Uri " + uri.toSafeString());
9921            }
9922
9923            if (exactPerm != null) {
9924                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9925                removeUriPermissionIfNeededLocked(exactPerm);
9926            }
9927            if (prefixPerm != null) {
9928                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9929                removeUriPermissionIfNeededLocked(prefixPerm);
9930            }
9931
9932            if (persistChanged) {
9933                schedulePersistUriGrants();
9934            }
9935        }
9936    }
9937
9938    /**
9939     * Prune any older {@link UriPermission} for the given UID until outstanding
9940     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9941     *
9942     * @return if any mutations occured that require persisting.
9943     */
9944    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9945        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9946        if (perms == null) return false;
9947        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9948
9949        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9950        for (UriPermission perm : perms.values()) {
9951            if (perm.persistedModeFlags != 0) {
9952                persisted.add(perm);
9953            }
9954        }
9955
9956        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9957        if (trimCount <= 0) return false;
9958
9959        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9960        for (int i = 0; i < trimCount; i++) {
9961            final UriPermission perm = persisted.get(i);
9962
9963            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9964                    "Trimming grant created at " + perm.persistedCreateTime);
9965
9966            perm.releasePersistableModes(~0);
9967            removeUriPermissionIfNeededLocked(perm);
9968        }
9969
9970        return true;
9971    }
9972
9973    @Override
9974    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9975            String packageName, boolean incoming) {
9976        enforceNotIsolatedCaller("getPersistedUriPermissions");
9977        Preconditions.checkNotNull(packageName, "packageName");
9978
9979        final int callingUid = Binder.getCallingUid();
9980        final int callingUserId = UserHandle.getUserId(callingUid);
9981        final IPackageManager pm = AppGlobals.getPackageManager();
9982        try {
9983            final int packageUid = pm.getPackageUid(packageName,
9984                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9985            if (packageUid != callingUid) {
9986                throw new SecurityException(
9987                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9988            }
9989        } catch (RemoteException e) {
9990            throw new SecurityException("Failed to verify package name ownership");
9991        }
9992
9993        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9994        synchronized (this) {
9995            if (incoming) {
9996                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9997                        callingUid);
9998                if (perms == null) {
9999                    Slog.w(TAG, "No permission grants found for " + packageName);
10000                } else {
10001                    for (UriPermission perm : perms.values()) {
10002                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
10003                            result.add(perm.buildPersistedPublicApiObject());
10004                        }
10005                    }
10006                }
10007            } else {
10008                final int size = mGrantedUriPermissions.size();
10009                for (int i = 0; i < size; i++) {
10010                    final ArrayMap<GrantUri, UriPermission> perms =
10011                            mGrantedUriPermissions.valueAt(i);
10012                    for (UriPermission perm : perms.values()) {
10013                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
10014                            result.add(perm.buildPersistedPublicApiObject());
10015                        }
10016                    }
10017                }
10018            }
10019        }
10020        return new ParceledListSlice<android.content.UriPermission>(result);
10021    }
10022
10023    @Override
10024    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
10025            String packageName, int userId) {
10026        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10027                "getGrantedUriPermissions");
10028
10029        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10030        synchronized (this) {
10031            final int size = mGrantedUriPermissions.size();
10032            for (int i = 0; i < size; i++) {
10033                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10034                for (UriPermission perm : perms.values()) {
10035                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
10036                            && perm.persistedModeFlags != 0) {
10037                        result.add(perm.buildPersistedPublicApiObject());
10038                    }
10039                }
10040            }
10041        }
10042        return new ParceledListSlice<android.content.UriPermission>(result);
10043    }
10044
10045    @Override
10046    public void clearGrantedUriPermissions(String packageName, int userId) {
10047        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
10048                "clearGrantedUriPermissions");
10049        removeUriPermissionsForPackageLocked(packageName, userId, true);
10050    }
10051
10052    @Override
10053    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
10054        synchronized (this) {
10055            ProcessRecord app =
10056                who != null ? getRecordForAppLocked(who) : null;
10057            if (app == null) return;
10058
10059            Message msg = Message.obtain();
10060            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
10061            msg.obj = app;
10062            msg.arg1 = waiting ? 1 : 0;
10063            mUiHandler.sendMessage(msg);
10064        }
10065    }
10066
10067    @Override
10068    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
10069        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
10070        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
10071        outInfo.availMem = getFreeMemory();
10072        outInfo.totalMem = getTotalMemory();
10073        outInfo.threshold = homeAppMem;
10074        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
10075        outInfo.hiddenAppThreshold = cachedAppMem;
10076        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
10077                ProcessList.SERVICE_ADJ);
10078        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
10079                ProcessList.VISIBLE_APP_ADJ);
10080        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
10081                ProcessList.FOREGROUND_APP_ADJ);
10082    }
10083
10084    // =========================================================
10085    // TASK MANAGEMENT
10086    // =========================================================
10087
10088    @Override
10089    public List<IBinder> getAppTasks(String callingPackage) {
10090        int callingUid = Binder.getCallingUid();
10091        long ident = Binder.clearCallingIdentity();
10092        try {
10093            synchronized(this) {
10094                return mRecentTasks.getAppTasksList(callingUid, callingPackage);
10095            }
10096        } finally {
10097            Binder.restoreCallingIdentity(ident);
10098        }
10099    }
10100
10101    @Override
10102    public List<RunningTaskInfo> getTasks(int maxNum) {
10103       return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
10104    }
10105
10106    @Override
10107    public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
10108            @WindowingMode int ignoreWindowingMode) {
10109        final int callingUid = Binder.getCallingUid();
10110        ArrayList<RunningTaskInfo> list = new ArrayList<>();
10111
10112        synchronized(this) {
10113            if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
10114
10115            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
10116                    callingUid);
10117            mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
10118                    ignoreWindowingMode, callingUid, allowed);
10119        }
10120
10121        return list;
10122    }
10123
10124    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
10125        if (mRecentTasks.isCallerRecents(callingUid)) {
10126            // Always allow the recents component to get tasks
10127            return true;
10128        }
10129
10130        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
10131                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
10132        if (!allowed) {
10133            if (checkPermission(android.Manifest.permission.GET_TASKS,
10134                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
10135                // Temporary compatibility: some existing apps on the system image may
10136                // still be requesting the old permission and not switched to the new
10137                // one; if so, we'll still allow them full access.  This means we need
10138                // to see if they are holding the old permission and are a system app.
10139                try {
10140                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
10141                        allowed = true;
10142                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10143                                + " is using old GET_TASKS but privileged; allowing");
10144                    }
10145                } catch (RemoteException e) {
10146                }
10147            }
10148        }
10149        if (!allowed) {
10150            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10151                    + " does not hold REAL_GET_TASKS; limiting output");
10152        }
10153        return allowed;
10154    }
10155
10156    @Override
10157    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
10158            int userId) {
10159        final int callingUid = Binder.getCallingUid();
10160        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
10161                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
10162        final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
10163                callingUid);
10164        final boolean detailed = checkCallingPermission(
10165                android.Manifest.permission.GET_DETAILED_TASKS)
10166                        == PackageManager.PERMISSION_GRANTED;
10167
10168        synchronized (this) {
10169            return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
10170                    callingUid);
10171        }
10172    }
10173
10174    @Override
10175    public ActivityManager.TaskDescription getTaskDescription(int id) {
10176        synchronized (this) {
10177            enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
10178            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10179                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10180            if (tr != null) {
10181                return tr.lastTaskDescription;
10182            }
10183        }
10184        return null;
10185    }
10186
10187    @Override
10188    public int addAppTask(IBinder activityToken, Intent intent,
10189            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10190        final int callingUid = Binder.getCallingUid();
10191        final long callingIdent = Binder.clearCallingIdentity();
10192
10193        try {
10194            synchronized (this) {
10195                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10196                if (r == null) {
10197                    throw new IllegalArgumentException("Activity does not exist; token="
10198                            + activityToken);
10199                }
10200                ComponentName comp = intent.getComponent();
10201                if (comp == null) {
10202                    throw new IllegalArgumentException("Intent " + intent
10203                            + " must specify explicit component");
10204                }
10205                if (thumbnail.getWidth() != mThumbnailWidth
10206                        || thumbnail.getHeight() != mThumbnailHeight) {
10207                    throw new IllegalArgumentException("Bad thumbnail size: got "
10208                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10209                            + mThumbnailWidth + "x" + mThumbnailHeight);
10210                }
10211                if (intent.getSelector() != null) {
10212                    intent.setSelector(null);
10213                }
10214                if (intent.getSourceBounds() != null) {
10215                    intent.setSourceBounds(null);
10216                }
10217                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10218                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10219                        // The caller has added this as an auto-remove task...  that makes no
10220                        // sense, so turn off auto-remove.
10221                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10222                    }
10223                }
10224                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10225                    mLastAddedTaskActivity = null;
10226                }
10227                ActivityInfo ainfo = mLastAddedTaskActivity;
10228                if (ainfo == null) {
10229                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10230                            comp, 0, UserHandle.getUserId(callingUid));
10231                    if (ainfo.applicationInfo.uid != callingUid) {
10232                        throw new SecurityException(
10233                                "Can't add task for another application: target uid="
10234                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10235                    }
10236                }
10237
10238                TaskRecord task = TaskRecord.create(this,
10239                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10240                        ainfo, intent, description);
10241                if (!mRecentTasks.addToBottom(task)) {
10242                    return INVALID_TASK_ID;
10243                }
10244                r.getStack().addTask(task, !ON_TOP, "addAppTask");
10245
10246                // TODO: Send the thumbnail to WM to store it.
10247
10248                return task.taskId;
10249            }
10250        } finally {
10251            Binder.restoreCallingIdentity(callingIdent);
10252        }
10253    }
10254
10255    @Override
10256    public Point getAppTaskThumbnailSize() {
10257        synchronized (this) {
10258            return new Point(mThumbnailWidth,  mThumbnailHeight);
10259        }
10260    }
10261
10262    @Override
10263    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10264        synchronized (this) {
10265            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10266            if (r != null) {
10267                r.setTaskDescription(td);
10268                final TaskRecord task = r.getTask();
10269                task.updateTaskDescription();
10270                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10271            }
10272        }
10273    }
10274
10275    @Override
10276    public void setTaskResizeable(int taskId, int resizeableMode) {
10277        synchronized (this) {
10278            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10279                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10280            if (task == null) {
10281                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10282                return;
10283            }
10284            task.setResizeMode(resizeableMode);
10285        }
10286    }
10287
10288    @Override
10289    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10290        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10291        long ident = Binder.clearCallingIdentity();
10292        try {
10293            synchronized (this) {
10294                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10295                if (task == null) {
10296                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10297                    return;
10298                }
10299                // Place the task in the right stack if it isn't there already based on
10300                // the requested bounds.
10301                // The stack transition logic is:
10302                // - a null bounds on a freeform task moves that task to fullscreen
10303                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10304                //   that task to freeform
10305                // - otherwise the task is not moved
10306                ActivityStack stack = task.getStack();
10307                if (!task.getWindowConfiguration().canResizeTask()) {
10308                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10309                }
10310                if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
10311                    stack = stack.getDisplay().getOrCreateStack(
10312                            WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10313                } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
10314                    stack = stack.getDisplay().getOrCreateStack(
10315                            WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
10316                }
10317
10318                // Reparent the task to the right stack if necessary
10319                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10320                if (stack != task.getStack()) {
10321                    // Defer resume until the task is resized below
10322                    task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10323                            DEFER_RESUME, "resizeTask");
10324                    preserveWindow = false;
10325                }
10326
10327                // After reparenting (which only resizes the task to the stack bounds), resize the
10328                // task to the actual bounds provided
10329                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10330            }
10331        } finally {
10332            Binder.restoreCallingIdentity(ident);
10333        }
10334    }
10335
10336    @Override
10337    public Rect getTaskBounds(int taskId) {
10338        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10339        long ident = Binder.clearCallingIdentity();
10340        Rect rect = new Rect();
10341        try {
10342            synchronized (this) {
10343                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10344                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10345                if (task == null) {
10346                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10347                    return rect;
10348                }
10349                if (task.getStack() != null) {
10350                    // Return the bounds from window manager since it will be adjusted for various
10351                    // things like the presense of a docked stack for tasks that aren't resizeable.
10352                    task.getWindowContainerBounds(rect);
10353                } else {
10354                    // Task isn't in window manager yet since it isn't associated with a stack.
10355                    // Return the persist value from activity manager
10356                    if (!task.matchParentBounds()) {
10357                        rect.set(task.getBounds());
10358                    } else if (task.mLastNonFullscreenBounds != null) {
10359                        rect.set(task.mLastNonFullscreenBounds);
10360                    }
10361                }
10362            }
10363        } finally {
10364            Binder.restoreCallingIdentity(ident);
10365        }
10366        return rect;
10367    }
10368
10369    @Override
10370    public void cancelTaskWindowTransition(int taskId) {
10371        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10372                "cancelTaskWindowTransition()");
10373        final long ident = Binder.clearCallingIdentity();
10374        try {
10375            synchronized (this) {
10376                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10377                        MATCH_TASK_IN_STACKS_ONLY);
10378                if (task == null) {
10379                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10380                    return;
10381                }
10382                task.cancelWindowTransition();
10383            }
10384        } finally {
10385            Binder.restoreCallingIdentity(ident);
10386        }
10387    }
10388
10389    @Override
10390    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10391        enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10392        final long ident = Binder.clearCallingIdentity();
10393        try {
10394            final TaskRecord task;
10395            synchronized (this) {
10396                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10397                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10398                if (task == null) {
10399                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10400                    return null;
10401                }
10402            }
10403            // Don't call this while holding the lock as this operation might hit the disk.
10404            return task.getSnapshot(reducedResolution);
10405        } finally {
10406            Binder.restoreCallingIdentity(ident);
10407        }
10408    }
10409
10410    @Override
10411    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10412        if (userId != UserHandle.getCallingUserId()) {
10413            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10414                    "getTaskDescriptionIcon");
10415        }
10416        final File passedIconFile = new File(filePath);
10417        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10418                passedIconFile.getName());
10419        if (!legitIconFile.getPath().equals(filePath)
10420                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10421            throw new IllegalArgumentException("Bad file path: " + filePath
10422                    + " passed for userId " + userId);
10423        }
10424        return mRecentTasks.getTaskDescriptionIcon(filePath);
10425    }
10426
10427    @Override
10428    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10429            throws RemoteException {
10430        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10431        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10432                activityOptions.getCustomInPlaceResId() == 0) {
10433            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10434                    "with valid animation");
10435        }
10436        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10437        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10438                activityOptions.getCustomInPlaceResId());
10439        mWindowManager.executeAppTransition();
10440    }
10441
10442    @Override
10443    public void removeStack(int stackId) {
10444        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
10445        synchronized (this) {
10446            final long ident = Binder.clearCallingIdentity();
10447            try {
10448                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10449                if (stack == null) {
10450                    Slog.w(TAG, "removeStack: No stack with id=" + stackId);
10451                    return;
10452                }
10453                if (!stack.isActivityTypeStandardOrUndefined()) {
10454                    throw new IllegalArgumentException(
10455                            "Removing non-standard stack is not allowed.");
10456                }
10457                mStackSupervisor.removeStack(stack);
10458            } finally {
10459                Binder.restoreCallingIdentity(ident);
10460            }
10461        }
10462    }
10463
10464    /**
10465     * Removes stacks in the input windowing modes from the system if they are of activity type
10466     * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
10467     */
10468    @Override
10469    public void removeStacksInWindowingModes(int[] windowingModes) {
10470        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10471                "removeStacksInWindowingModes()");
10472        synchronized (this) {
10473            final long ident = Binder.clearCallingIdentity();
10474            try {
10475                mStackSupervisor.removeStacksInWindowingModes(windowingModes);
10476            } finally {
10477                Binder.restoreCallingIdentity(ident);
10478            }
10479        }
10480    }
10481
10482    @Override
10483    public void removeStacksWithActivityTypes(int[] activityTypes) {
10484        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10485                "removeStacksWithActivityTypes()");
10486        synchronized (this) {
10487            final long ident = Binder.clearCallingIdentity();
10488            try {
10489                mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
10490            } finally {
10491                Binder.restoreCallingIdentity(ident);
10492            }
10493        }
10494    }
10495
10496    @Override
10497    public void moveStackToDisplay(int stackId, int displayId) {
10498        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10499
10500        synchronized (this) {
10501            final long ident = Binder.clearCallingIdentity();
10502            try {
10503                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10504                        + " to displayId=" + displayId);
10505                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10506            } finally {
10507                Binder.restoreCallingIdentity(ident);
10508            }
10509        }
10510    }
10511
10512    @Override
10513    public boolean removeTask(int taskId) {
10514        enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
10515        synchronized (this) {
10516            final long ident = Binder.clearCallingIdentity();
10517            try {
10518                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
10519                        "remove-task");
10520            } finally {
10521                Binder.restoreCallingIdentity(ident);
10522            }
10523        }
10524    }
10525
10526    /**
10527     * TODO: Add mController hook
10528     */
10529    @Override
10530    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10531        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10532
10533        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10534        synchronized(this) {
10535            moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10536        }
10537    }
10538
10539    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10540        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10541
10542        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10543                Binder.getCallingUid(), -1, -1, "Task to front")) {
10544            ActivityOptions.abort(options);
10545            return;
10546        }
10547        final long origId = Binder.clearCallingIdentity();
10548        try {
10549            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10550            if (task == null) {
10551                Slog.d(TAG, "Could not find task for id: "+ taskId);
10552                return;
10553            }
10554            if (mLockTaskController.isLockTaskModeViolation(task)) {
10555                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10556                return;
10557            }
10558            mStackSupervisor.findTaskToMoveToFront(task, flags, options, "moveTaskToFront",
10559                    false /* forceNonResizable */);
10560
10561            final ActivityRecord topActivity = task.getTopActivity();
10562            if (topActivity != null) {
10563
10564                // We are reshowing a task, use a starting window to hide the initial draw delay
10565                // so the transition can start earlier.
10566                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10567                        true /* taskSwitch */, fromRecents);
10568            }
10569        } finally {
10570            Binder.restoreCallingIdentity(origId);
10571        }
10572        ActivityOptions.abort(options);
10573    }
10574
10575    /**
10576     * Attempts to move a task backwards in z-order (the order of activities within the task is
10577     * unchanged).
10578     *
10579     * There are several possible results of this call:
10580     * - if the task is locked, then we will show the lock toast
10581     * - if there is a task behind the provided task, then that task is made visible and resumed as
10582     *   this task is moved to the back
10583     * - otherwise, if there are no other tasks in the stack:
10584     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10585     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10586     *       (depending on whether it is visible)
10587     *     - otherwise, we simply return home and hide this task
10588     *
10589     * @param token A reference to the activity we wish to move
10590     * @param nonRoot If false then this only works if the activity is the root
10591     *                of a task; if true it will work for any activity in a task.
10592     * @return Returns true if the move completed, false if not.
10593     */
10594    @Override
10595    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10596        enforceNotIsolatedCaller("moveActivityTaskToBack");
10597        synchronized(this) {
10598            final long origId = Binder.clearCallingIdentity();
10599            try {
10600                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10601                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10602                if (task != null) {
10603                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10604                }
10605            } finally {
10606                Binder.restoreCallingIdentity(origId);
10607            }
10608        }
10609        return false;
10610    }
10611
10612    @Override
10613    public void moveTaskBackwards(int task) {
10614        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10615                "moveTaskBackwards()");
10616
10617        synchronized(this) {
10618            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10619                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10620                return;
10621            }
10622            final long origId = Binder.clearCallingIdentity();
10623            moveTaskBackwardsLocked(task);
10624            Binder.restoreCallingIdentity(origId);
10625        }
10626    }
10627
10628    private final void moveTaskBackwardsLocked(int task) {
10629        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10630    }
10631
10632    @Override
10633    public int createStackOnDisplay(int displayId) throws RemoteException {
10634        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10635        synchronized (this) {
10636            final ActivityDisplay display =
10637                    mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
10638            if (display == null) {
10639                return INVALID_STACK_ID;
10640            }
10641            // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
10642            final ActivityStack stack = display.createStack(
10643                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
10644                    ON_TOP);
10645            return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
10646        }
10647    }
10648
10649    @Override
10650    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10651        synchronized (this) {
10652            final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10653            if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10654                return stack.mDisplayId;
10655            }
10656            return DEFAULT_DISPLAY;
10657        }
10658    }
10659
10660    @Override
10661    public void exitFreeformMode(IBinder token) throws RemoteException {
10662        synchronized (this) {
10663            long ident = Binder.clearCallingIdentity();
10664            try {
10665                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10666                if (r == null) {
10667                    throw new IllegalArgumentException(
10668                            "exitFreeformMode: No activity record matching token=" + token);
10669                }
10670
10671                final ActivityStack stack = r.getStack();
10672                if (stack == null || !stack.inFreeformWindowingMode()) {
10673                    throw new IllegalStateException(
10674                            "exitFreeformMode: You can only go fullscreen from freeform.");
10675                }
10676
10677                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
10678            } finally {
10679                Binder.restoreCallingIdentity(ident);
10680            }
10681        }
10682    }
10683
10684    @Override
10685    public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
10686        if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
10687            setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
10688                    toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
10689            return;
10690        }
10691        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
10692        synchronized (this) {
10693            final long ident = Binder.clearCallingIdentity();
10694            try {
10695                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10696                if (task == null) {
10697                    Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
10698                    return;
10699                }
10700
10701                if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
10702                        + " to windowingMode=" + windowingMode + " toTop=" + toTop);
10703
10704                if (!task.isActivityTypeStandardOrUndefined()) {
10705                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
10706                            + " non-standard task " + taskId + " to windowing mode="
10707                            + windowingMode);
10708                }
10709
10710                final ActivityStack stack = task.getStack();
10711                if (toTop) {
10712                    stack.moveToFront("setTaskWindowingMode", task);
10713                }
10714                stack.setWindowingMode(windowingMode);
10715            } finally {
10716                Binder.restoreCallingIdentity(ident);
10717            }
10718        }
10719    }
10720
10721    /**
10722     * Moves the specified task to the primary-split-screen stack.
10723     *
10724     * @param taskId Id of task to move.
10725     * @param createMode The mode the primary split screen stack should be created in if it doesn't
10726     *                   exist already. See
10727     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
10728     *                   and
10729     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
10730     * @param toTop If the task and stack should be moved to the top.
10731     * @param animate Whether we should play an animation for the moving the task.
10732     * @param initialBounds If the primary stack gets created, it will use these bounds for the
10733     *                      stack. Pass {@code null} to use default bounds.
10734     * @param showRecents If the recents activity should be shown on the other side of the task
10735     *                    going into split-screen mode.
10736     */
10737    @Override
10738    public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
10739            boolean animate, Rect initialBounds, boolean showRecents) {
10740        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10741                "setTaskWindowingModeSplitScreenPrimary()");
10742        synchronized (this) {
10743            long ident = Binder.clearCallingIdentity();
10744            try {
10745                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10746                if (task == null) {
10747                    Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
10748                    return false;
10749                }
10750                if (DEBUG_STACK) Slog.d(TAG_STACK,
10751                        "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
10752                        + " to createMode=" + createMode + " toTop=" + toTop);
10753                if (!task.isActivityTypeStandardOrUndefined()) {
10754                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
10755                            + " non-standard task " + taskId + " to split-screen windowing mode");
10756                }
10757
10758                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10759                final int windowingMode = task.getWindowingMode();
10760                final ActivityStack stack = task.getStack();
10761                if (toTop) {
10762                    stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
10763                }
10764                stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
10765                        false /* enteringSplitScreenMode */);
10766                return windowingMode != task.getWindowingMode();
10767            } finally {
10768                Binder.restoreCallingIdentity(ident);
10769            }
10770        }
10771    }
10772
10773    @Override
10774    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10775        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10776        synchronized (this) {
10777            long ident = Binder.clearCallingIdentity();
10778            try {
10779                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10780                if (task == null) {
10781                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10782                    return;
10783                }
10784
10785                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10786                        + " to stackId=" + stackId + " toTop=" + toTop);
10787
10788                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10789                if (stack == null) {
10790                    throw new IllegalStateException(
10791                            "moveTaskToStack: No stack for stackId=" + stackId);
10792                }
10793                if (!stack.isActivityTypeStandardOrUndefined()) {
10794                    throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
10795                            + taskId + " to stack " + stackId);
10796                }
10797                if (stack.inSplitScreenPrimaryWindowingMode()) {
10798                    mWindowManager.setDockedStackCreateState(
10799                            SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
10800                }
10801                task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
10802                        "moveTaskToStack");
10803            } finally {
10804                Binder.restoreCallingIdentity(ident);
10805            }
10806        }
10807    }
10808
10809    /**
10810     * Dismisses split-screen multi-window mode.
10811     * @param toTop If true the current primary split-screen stack will be placed or left on top.
10812     */
10813    @Override
10814    public void dismissSplitScreenMode(boolean toTop) {
10815        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
10816        final long ident = Binder.clearCallingIdentity();
10817        try {
10818            synchronized (this) {
10819                final ActivityStack stack =
10820                        mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
10821                if (stack == null) {
10822                    Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
10823                    return;
10824                }
10825
10826                if (toTop) {
10827                    stack.moveToFront("dismissSplitScreenMode");
10828                }
10829                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
10830            }
10831        } finally {
10832            Binder.restoreCallingIdentity(ident);
10833        }
10834    }
10835
10836    /**
10837     * Dismisses Pip
10838     * @param animate True if the dismissal should be animated.
10839     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
10840     *                          default animation duration should be used.
10841     */
10842    @Override
10843    public void dismissPip(boolean animate, int animationDuration) {
10844        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
10845        final long ident = Binder.clearCallingIdentity();
10846        try {
10847            synchronized (this) {
10848                final PinnedActivityStack stack =
10849                        mStackSupervisor.getDefaultDisplay().getPinnedStack();
10850                if (stack == null) {
10851                    Slog.w(TAG, "dismissPip: pinned stack not found.");
10852                    return;
10853                }
10854                if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
10855                    throw new IllegalArgumentException("Stack: " + stack
10856                            + " doesn't support animated resize.");
10857                }
10858                if (animate) {
10859                    stack.animateResizePinnedStack(null /* sourceHintBounds */,
10860                            null /* destBounds */, animationDuration, false /* fromFullscreen */);
10861                } else {
10862                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
10863                }
10864            }
10865        } finally {
10866            Binder.restoreCallingIdentity(ident);
10867        }
10868    }
10869
10870    /**
10871     * Moves the top activity in the input stackId to the pinned stack.
10872     *
10873     * @param stackId Id of stack to move the top activity to pinned stack.
10874     * @param bounds Bounds to use for pinned stack.
10875     *
10876     * @return True if the top activity of the input stack was successfully moved to the pinned
10877     *          stack.
10878     */
10879    @Override
10880    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10881        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10882                "moveTopActivityToPinnedStack()");
10883        synchronized (this) {
10884            if (!mSupportsPictureInPicture) {
10885                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10886                        + "Device doesn't support picture-in-picture mode");
10887            }
10888
10889            long ident = Binder.clearCallingIdentity();
10890            try {
10891                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10892            } finally {
10893                Binder.restoreCallingIdentity(ident);
10894            }
10895        }
10896    }
10897
10898    @Override
10899    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10900            boolean preserveWindows, boolean animate, int animationDuration) {
10901        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10902        long ident = Binder.clearCallingIdentity();
10903        try {
10904            synchronized (this) {
10905                if (animate) {
10906                    final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
10907                    if (stack == null) {
10908                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
10909                        return;
10910                    }
10911                    if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
10912                        throw new IllegalArgumentException("Stack: " + stackId
10913                                + " doesn't support animated resize.");
10914                    }
10915                    stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
10916                            animationDuration, false /* fromFullscreen */);
10917                } else {
10918                    final ActivityStack stack = mStackSupervisor.getStack(stackId);
10919                    if (stack == null) {
10920                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
10921                        return;
10922                    }
10923                    mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
10924                            null /* tempTaskInsetBounds */, preserveWindows,
10925                            allowResizeInDockedMode, !DEFER_RESUME);
10926                }
10927            }
10928        } finally {
10929            Binder.restoreCallingIdentity(ident);
10930        }
10931    }
10932
10933    @Override
10934    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10935            Rect tempDockedTaskInsetBounds,
10936            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10937        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
10938        long ident = Binder.clearCallingIdentity();
10939        try {
10940            synchronized (this) {
10941                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10942                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10943                        PRESERVE_WINDOWS);
10944            }
10945        } finally {
10946            Binder.restoreCallingIdentity(ident);
10947        }
10948    }
10949
10950    @Override
10951    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10952        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
10953        final long ident = Binder.clearCallingIdentity();
10954        try {
10955            synchronized (this) {
10956                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10957            }
10958        } finally {
10959            Binder.restoreCallingIdentity(ident);
10960        }
10961    }
10962
10963    /**
10964     * Try to place task to provided position. The final position might be different depending on
10965     * current user and stacks state. The task will be moved to target stack if it's currently in
10966     * different stack.
10967     */
10968    @Override
10969    public void positionTaskInStack(int taskId, int stackId, int position) {
10970        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10971        synchronized (this) {
10972            long ident = Binder.clearCallingIdentity();
10973            try {
10974                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10975                        + taskId + " in stackId=" + stackId + " at position=" + position);
10976                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10977                if (task == null) {
10978                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10979                            + taskId);
10980                }
10981
10982                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10983
10984                if (stack == null) {
10985                    throw new IllegalArgumentException("positionTaskInStack: no stack for id="
10986                            + stackId);
10987                }
10988                if (!stack.isActivityTypeStandardOrUndefined()) {
10989                    throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
10990                            + " the position of task " + taskId + " in/to non-standard stack");
10991                }
10992
10993                // TODO: Have the callers of this API call a separate reparent method if that is
10994                // what they intended to do vs. having this method also do reparenting.
10995                if (task.getStack() == stack) {
10996                    // Change position in current stack.
10997                    stack.positionChildAt(task, position);
10998                } else {
10999                    // Reparent to new stack.
11000                    task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
11001                            !DEFER_RESUME, "positionTaskInStack");
11002                }
11003            } finally {
11004                Binder.restoreCallingIdentity(ident);
11005            }
11006        }
11007    }
11008
11009    @Override
11010    public List<StackInfo> getAllStackInfos() {
11011        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
11012        long ident = Binder.clearCallingIdentity();
11013        try {
11014            synchronized (this) {
11015                return mStackSupervisor.getAllStackInfosLocked();
11016            }
11017        } finally {
11018            Binder.restoreCallingIdentity(ident);
11019        }
11020    }
11021
11022    @Override
11023    public StackInfo getStackInfo(int windowingMode, int activityType) {
11024        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
11025        long ident = Binder.clearCallingIdentity();
11026        try {
11027            synchronized (this) {
11028                return mStackSupervisor.getStackInfo(windowingMode, activityType);
11029            }
11030        } finally {
11031            Binder.restoreCallingIdentity(ident);
11032        }
11033    }
11034
11035    @Override
11036    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
11037        synchronized(this) {
11038            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
11039        }
11040    }
11041
11042    @Override
11043    public void updateDeviceOwner(String packageName) {
11044        final int callingUid = Binder.getCallingUid();
11045        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11046            throw new SecurityException("updateDeviceOwner called from non-system process");
11047        }
11048        synchronized (this) {
11049            mDeviceOwnerName = packageName;
11050        }
11051    }
11052
11053    @Override
11054    public void updateLockTaskPackages(int userId, String[] packages) {
11055        final int callingUid = Binder.getCallingUid();
11056        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11057            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11058                    "updateLockTaskPackages()");
11059        }
11060        synchronized (this) {
11061            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
11062                    Arrays.toString(packages));
11063            mLockTaskController.updateLockTaskPackages(userId, packages);
11064        }
11065    }
11066
11067    @Override
11068    public void updateLockTaskFeatures(int userId, int flags) {
11069        final int callingUid = Binder.getCallingUid();
11070        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11071            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11072                    "updateLockTaskFeatures()");
11073        }
11074        synchronized (this) {
11075            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
11076                    Integer.toHexString(flags));
11077            mLockTaskController.updateLockTaskFeatures(userId, flags);
11078        }
11079    }
11080
11081    private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
11082        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
11083        if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
11084            return;
11085        }
11086
11087        final ActivityStack stack = mStackSupervisor.getFocusedStack();
11088        if (stack == null || task != stack.topTask()) {
11089            throw new IllegalArgumentException("Invalid task, not in foreground");
11090        }
11091
11092        // When a task is locked, dismiss the pinned stack if it exists
11093        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
11094
11095        // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
11096        // system or a specific app.
11097        // * System-initiated requests will only start the pinned mode (screen pinning)
11098        // * App-initiated requests
11099        //   - will put the device in fully locked mode (LockTask), if the app is whitelisted
11100        //   - will start the pinned mode, otherwise
11101        final int callingUid = Binder.getCallingUid();
11102        long ident = Binder.clearCallingIdentity();
11103        try {
11104            mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
11105        } finally {
11106            Binder.restoreCallingIdentity(ident);
11107        }
11108    }
11109
11110    @Override
11111    public void startLockTaskModeByToken(IBinder token) {
11112        synchronized (this) {
11113            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11114            if (r == null) {
11115                return;
11116            }
11117            startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
11118        }
11119    }
11120
11121    @Override
11122    public void startSystemLockTaskMode(int taskId) throws RemoteException {
11123        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11124        // This makes inner call to look as if it was initiated by system.
11125        long ident = Binder.clearCallingIdentity();
11126        try {
11127            synchronized (this) {
11128                startLockTaskModeLocked(mStackSupervisor.anyTaskForIdLocked(taskId),
11129                        true /* isSystemCaller */);
11130            }
11131        } finally {
11132            Binder.restoreCallingIdentity(ident);
11133        }
11134    }
11135
11136    @Override
11137    public void stopLockTaskModeByToken(IBinder token) {
11138        synchronized (this) {
11139            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11140            if (r == null) {
11141                return;
11142            }
11143            stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
11144        }
11145    }
11146
11147    /**
11148     * This API should be called by SystemUI only when user perform certain action to dismiss
11149     * lock task mode. We should only dismiss pinned lock task mode in this case.
11150     */
11151    @Override
11152    public void stopSystemLockTaskMode() throws RemoteException {
11153        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
11154        stopLockTaskModeInternal(null, true /* isSystemCaller */);
11155    }
11156
11157    private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
11158        final int callingUid = Binder.getCallingUid();
11159        long ident = Binder.clearCallingIdentity();
11160        try {
11161            synchronized (this) {
11162                mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
11163            }
11164            // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
11165            // task and jumping straight into a call in the case of emergency call back.
11166            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11167            if (tm != null) {
11168                tm.showInCallScreen(false);
11169            }
11170        } finally {
11171            Binder.restoreCallingIdentity(ident);
11172        }
11173    }
11174
11175    @Override
11176    public boolean isInLockTaskMode() {
11177        return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
11178    }
11179
11180    @Override
11181    public int getLockTaskModeState() {
11182        synchronized (this) {
11183            return mLockTaskController.getLockTaskModeState();
11184        }
11185    }
11186
11187    @Override
11188    public void showLockTaskEscapeMessage(IBinder token) {
11189        synchronized (this) {
11190            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11191            if (r == null) {
11192                return;
11193            }
11194            mLockTaskController.showLockTaskToast();
11195        }
11196    }
11197
11198    @Override
11199    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11200            throws RemoteException {
11201        synchronized (this) {
11202            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11203            if (r == null) {
11204                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11205                        + token);
11206                return;
11207            }
11208            final long origId = Binder.clearCallingIdentity();
11209            try {
11210                r.setDisablePreviewScreenshots(disable);
11211            } finally {
11212                Binder.restoreCallingIdentity(origId);
11213            }
11214        }
11215    }
11216
11217    // =========================================================
11218    // CONTENT PROVIDERS
11219    // =========================================================
11220
11221    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11222        List<ProviderInfo> providers = null;
11223        try {
11224            providers = AppGlobals.getPackageManager()
11225                    .queryContentProviders(app.processName, app.uid,
11226                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11227                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11228                    .getList();
11229        } catch (RemoteException ex) {
11230        }
11231        if (DEBUG_MU) Slog.v(TAG_MU,
11232                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11233        int userId = app.userId;
11234        if (providers != null) {
11235            int N = providers.size();
11236            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11237            for (int i=0; i<N; i++) {
11238                // TODO: keep logic in sync with installEncryptionUnawareProviders
11239                ProviderInfo cpi =
11240                    (ProviderInfo)providers.get(i);
11241                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11242                        cpi.name, cpi.flags);
11243                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11244                    // This is a singleton provider, but a user besides the
11245                    // default user is asking to initialize a process it runs
11246                    // in...  well, no, it doesn't actually run in this process,
11247                    // it runs in the process of the default user.  Get rid of it.
11248                    providers.remove(i);
11249                    N--;
11250                    i--;
11251                    continue;
11252                }
11253
11254                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11255                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11256                if (cpr == null) {
11257                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11258                    mProviderMap.putProviderByClass(comp, cpr);
11259                }
11260                if (DEBUG_MU) Slog.v(TAG_MU,
11261                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11262                app.pubProviders.put(cpi.name, cpr);
11263                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11264                    // Don't add this if it is a platform component that is marked
11265                    // to run in multiple processes, because this is actually
11266                    // part of the framework so doesn't make sense to track as a
11267                    // separate apk in the process.
11268                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11269                            mProcessStats);
11270                }
11271                notifyPackageUse(cpi.applicationInfo.packageName,
11272                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11273            }
11274        }
11275        return providers;
11276    }
11277
11278    /**
11279     * Check if the calling UID has a possible chance at accessing the provider
11280     * at the given authority and user.
11281     */
11282    public String checkContentProviderAccess(String authority, int userId) {
11283        if (userId == UserHandle.USER_ALL) {
11284            mContext.enforceCallingOrSelfPermission(
11285                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11286            userId = UserHandle.getCallingUserId();
11287        }
11288
11289        ProviderInfo cpi = null;
11290        try {
11291            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11292                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11293                            | PackageManager.MATCH_DISABLED_COMPONENTS
11294                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11295                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11296                    userId);
11297        } catch (RemoteException ignored) {
11298        }
11299        if (cpi == null) {
11300            return "Failed to find provider " + authority + " for user " + userId
11301                    + "; expected to find a valid ContentProvider for this authority";
11302        }
11303
11304        ProcessRecord r = null;
11305        synchronized (mPidsSelfLocked) {
11306            r = mPidsSelfLocked.get(Binder.getCallingPid());
11307        }
11308        if (r == null) {
11309            return "Failed to find PID " + Binder.getCallingPid();
11310        }
11311
11312        synchronized (this) {
11313            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11314        }
11315    }
11316
11317    /**
11318     * Check if {@link ProcessRecord} has a possible chance at accessing the
11319     * given {@link ProviderInfo}. Final permission checking is always done
11320     * in {@link ContentProvider}.
11321     */
11322    private final String checkContentProviderPermissionLocked(
11323            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11324        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11325        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11326        boolean checkedGrants = false;
11327        if (checkUser) {
11328            // Looking for cross-user grants before enforcing the typical cross-users permissions
11329            int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
11330            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11331                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11332                    return null;
11333                }
11334                checkedGrants = true;
11335            }
11336            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11337                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11338            if (userId != tmpTargetUserId) {
11339                // When we actually went to determine the final targer user ID, this ended
11340                // up different than our initial check for the authority.  This is because
11341                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11342                // SELF.  So we need to re-check the grants again.
11343                checkedGrants = false;
11344            }
11345        }
11346        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11347                cpi.applicationInfo.uid, cpi.exported)
11348                == PackageManager.PERMISSION_GRANTED) {
11349            return null;
11350        }
11351        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11352                cpi.applicationInfo.uid, cpi.exported)
11353                == PackageManager.PERMISSION_GRANTED) {
11354            return null;
11355        }
11356
11357        PathPermission[] pps = cpi.pathPermissions;
11358        if (pps != null) {
11359            int i = pps.length;
11360            while (i > 0) {
11361                i--;
11362                PathPermission pp = pps[i];
11363                String pprperm = pp.getReadPermission();
11364                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11365                        cpi.applicationInfo.uid, cpi.exported)
11366                        == PackageManager.PERMISSION_GRANTED) {
11367                    return null;
11368                }
11369                String ppwperm = pp.getWritePermission();
11370                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11371                        cpi.applicationInfo.uid, cpi.exported)
11372                        == PackageManager.PERMISSION_GRANTED) {
11373                    return null;
11374                }
11375            }
11376        }
11377        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11378            return null;
11379        }
11380
11381        final String suffix;
11382        if (!cpi.exported) {
11383            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11384        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11385            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11386        } else {
11387            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11388        }
11389        final String msg = "Permission Denial: opening provider " + cpi.name
11390                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11391                + ", uid=" + callingUid + ")" + suffix;
11392        Slog.w(TAG, msg);
11393        return msg;
11394    }
11395
11396    /**
11397     * Returns if the ContentProvider has granted a uri to callingUid
11398     */
11399    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11400        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11401        if (perms != null) {
11402            for (int i=perms.size()-1; i>=0; i--) {
11403                GrantUri grantUri = perms.keyAt(i);
11404                if (grantUri.sourceUserId == userId || !checkUser) {
11405                    if (matchesProvider(grantUri.uri, cpi)) {
11406                        return true;
11407                    }
11408                }
11409            }
11410        }
11411        return false;
11412    }
11413
11414    /**
11415     * Returns true if the uri authority is one of the authorities specified in the provider.
11416     */
11417    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11418        String uriAuth = uri.getAuthority();
11419        String cpiAuth = cpi.authority;
11420        if (cpiAuth.indexOf(';') == -1) {
11421            return cpiAuth.equals(uriAuth);
11422        }
11423        String[] cpiAuths = cpiAuth.split(";");
11424        int length = cpiAuths.length;
11425        for (int i = 0; i < length; i++) {
11426            if (cpiAuths[i].equals(uriAuth)) return true;
11427        }
11428        return false;
11429    }
11430
11431    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11432            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11433        if (r != null) {
11434            for (int i=0; i<r.conProviders.size(); i++) {
11435                ContentProviderConnection conn = r.conProviders.get(i);
11436                if (conn.provider == cpr) {
11437                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11438                            "Adding provider requested by "
11439                            + r.processName + " from process "
11440                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11441                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11442                    if (stable) {
11443                        conn.stableCount++;
11444                        conn.numStableIncs++;
11445                    } else {
11446                        conn.unstableCount++;
11447                        conn.numUnstableIncs++;
11448                    }
11449                    return conn;
11450                }
11451            }
11452            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11453            if (stable) {
11454                conn.stableCount = 1;
11455                conn.numStableIncs = 1;
11456            } else {
11457                conn.unstableCount = 1;
11458                conn.numUnstableIncs = 1;
11459            }
11460            cpr.connections.add(conn);
11461            r.conProviders.add(conn);
11462            startAssociationLocked(r.uid, r.processName, r.curProcState,
11463                    cpr.uid, cpr.name, cpr.info.processName);
11464            return conn;
11465        }
11466        cpr.addExternalProcessHandleLocked(externalProcessToken);
11467        return null;
11468    }
11469
11470    boolean decProviderCountLocked(ContentProviderConnection conn,
11471            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11472        if (conn != null) {
11473            cpr = conn.provider;
11474            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11475                    "Removing provider requested by "
11476                    + conn.client.processName + " from process "
11477                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11478                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11479            if (stable) {
11480                conn.stableCount--;
11481            } else {
11482                conn.unstableCount--;
11483            }
11484            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11485                cpr.connections.remove(conn);
11486                conn.client.conProviders.remove(conn);
11487                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11488                    // The client is more important than last activity -- note the time this
11489                    // is happening, so we keep the old provider process around a bit as last
11490                    // activity to avoid thrashing it.
11491                    if (cpr.proc != null) {
11492                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11493                    }
11494                }
11495                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11496                return true;
11497            }
11498            return false;
11499        }
11500        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11501        return false;
11502    }
11503
11504    private void checkTime(long startTime, String where) {
11505        long now = SystemClock.uptimeMillis();
11506        if ((now-startTime) > 50) {
11507            // If we are taking more than 50ms, log about it.
11508            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11509        }
11510    }
11511
11512    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11513            PROC_SPACE_TERM,
11514            PROC_SPACE_TERM|PROC_PARENS,
11515            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11516    };
11517
11518    private final long[] mProcessStateStatsLongs = new long[1];
11519
11520    private boolean isProcessAliveLocked(ProcessRecord proc) {
11521        if (proc.pid <= 0) {
11522            if (DEBUG_OOM_ADJ) Slog.d(TAG, "Process hasn't started yet: " + proc);
11523            return false;
11524        }
11525        if (proc.procStatFile == null) {
11526            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11527        }
11528        mProcessStateStatsLongs[0] = 0;
11529        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11530                mProcessStateStatsLongs, null)) {
11531            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11532            return false;
11533        }
11534        final long state = mProcessStateStatsLongs[0];
11535        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11536                + (char)state);
11537        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11538    }
11539
11540    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11541            String name, IBinder token, boolean stable, int userId) {
11542        ContentProviderRecord cpr;
11543        ContentProviderConnection conn = null;
11544        ProviderInfo cpi = null;
11545
11546        synchronized(this) {
11547            long startTime = SystemClock.uptimeMillis();
11548
11549            ProcessRecord r = null;
11550            if (caller != null) {
11551                r = getRecordForAppLocked(caller);
11552                if (r == null) {
11553                    throw new SecurityException(
11554                            "Unable to find app for caller " + caller
11555                          + " (pid=" + Binder.getCallingPid()
11556                          + ") when getting content provider " + name);
11557                }
11558            }
11559
11560            boolean checkCrossUser = true;
11561
11562            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11563
11564            // First check if this content provider has been published...
11565            cpr = mProviderMap.getProviderByName(name, userId);
11566            // If that didn't work, check if it exists for user 0 and then
11567            // verify that it's a singleton provider before using it.
11568            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11569                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11570                if (cpr != null) {
11571                    cpi = cpr.info;
11572                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11573                            cpi.name, cpi.flags)
11574                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11575                        userId = UserHandle.USER_SYSTEM;
11576                        checkCrossUser = false;
11577                    } else {
11578                        cpr = null;
11579                        cpi = null;
11580                    }
11581                }
11582            }
11583
11584            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11585            if (providerRunning) {
11586                cpi = cpr.info;
11587                String msg;
11588                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11589                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11590                        != null) {
11591                    throw new SecurityException(msg);
11592                }
11593                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11594
11595                if (r != null && cpr.canRunHere(r)) {
11596                    // This provider has been published or is in the process
11597                    // of being published...  but it is also allowed to run
11598                    // in the caller's process, so don't make a connection
11599                    // and just let the caller instantiate its own instance.
11600                    ContentProviderHolder holder = cpr.newHolder(null);
11601                    // don't give caller the provider object, it needs
11602                    // to make its own.
11603                    holder.provider = null;
11604                    return holder;
11605                }
11606                // Don't expose providers between normal apps and instant apps
11607                try {
11608                    if (AppGlobals.getPackageManager()
11609                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11610                        return null;
11611                    }
11612                } catch (RemoteException e) {
11613                }
11614
11615                final long origId = Binder.clearCallingIdentity();
11616
11617                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11618
11619                // In this case the provider instance already exists, so we can
11620                // return it right away.
11621                conn = incProviderCountLocked(r, cpr, token, stable);
11622                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11623                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11624                        // If this is a perceptible app accessing the provider,
11625                        // make sure to count it as being accessed and thus
11626                        // back up on the LRU list.  This is good because
11627                        // content providers are often expensive to start.
11628                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11629                        updateLruProcessLocked(cpr.proc, false, null);
11630                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11631                    }
11632                }
11633
11634                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11635                final int verifiedAdj = cpr.proc.verifiedAdj;
11636                boolean success = updateOomAdjLocked(cpr.proc, true);
11637                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11638                // if the process has been successfully adjusted.  So to reduce races with
11639                // it, we will check whether the process still exists.  Note that this doesn't
11640                // completely get rid of races with LMK killing the process, but should make
11641                // them much smaller.
11642                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11643                    success = false;
11644                }
11645                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11646                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11647                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11648                // NOTE: there is still a race here where a signal could be
11649                // pending on the process even though we managed to update its
11650                // adj level.  Not sure what to do about this, but at least
11651                // the race is now smaller.
11652                if (!success) {
11653                    // Uh oh...  it looks like the provider's process
11654                    // has been killed on us.  We need to wait for a new
11655                    // process to be started, and make sure its death
11656                    // doesn't kill our process.
11657                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11658                            + " is crashing; detaching " + r);
11659                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11660                    checkTime(startTime, "getContentProviderImpl: before appDied");
11661                    appDiedLocked(cpr.proc);
11662                    checkTime(startTime, "getContentProviderImpl: after appDied");
11663                    if (!lastRef) {
11664                        // This wasn't the last ref our process had on
11665                        // the provider...  we have now been killed, bail.
11666                        return null;
11667                    }
11668                    providerRunning = false;
11669                    conn = null;
11670                } else {
11671                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11672                }
11673
11674                Binder.restoreCallingIdentity(origId);
11675            }
11676
11677            if (!providerRunning) {
11678                try {
11679                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11680                    cpi = AppGlobals.getPackageManager().
11681                        resolveContentProvider(name,
11682                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11683                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11684                } catch (RemoteException ex) {
11685                }
11686                if (cpi == null) {
11687                    return null;
11688                }
11689                // If the provider is a singleton AND
11690                // (it's a call within the same user || the provider is a
11691                // privileged app)
11692                // Then allow connecting to the singleton provider
11693                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11694                        cpi.name, cpi.flags)
11695                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11696                if (singleton) {
11697                    userId = UserHandle.USER_SYSTEM;
11698                }
11699                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11700                checkTime(startTime, "getContentProviderImpl: got app info for user");
11701
11702                String msg;
11703                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11704                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11705                        != null) {
11706                    throw new SecurityException(msg);
11707                }
11708                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11709
11710                if (!mProcessesReady
11711                        && !cpi.processName.equals("system")) {
11712                    // If this content provider does not run in the system
11713                    // process, and the system is not yet ready to run other
11714                    // processes, then fail fast instead of hanging.
11715                    throw new IllegalArgumentException(
11716                            "Attempt to launch content provider before system ready");
11717                }
11718
11719                // Make sure that the user who owns this provider is running.  If not,
11720                // we don't want to allow it to run.
11721                if (!mUserController.isUserRunning(userId, 0)) {
11722                    Slog.w(TAG, "Unable to launch app "
11723                            + cpi.applicationInfo.packageName + "/"
11724                            + cpi.applicationInfo.uid + " for provider "
11725                            + name + ": user " + userId + " is stopped");
11726                    return null;
11727                }
11728
11729                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11730                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11731                cpr = mProviderMap.getProviderByClass(comp, userId);
11732                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11733                final boolean firstClass = cpr == null;
11734                if (firstClass) {
11735                    final long ident = Binder.clearCallingIdentity();
11736
11737                    // If permissions need a review before any of the app components can run,
11738                    // we return no provider and launch a review activity if the calling app
11739                    // is in the foreground.
11740                    if (mPermissionReviewRequired) {
11741                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11742                            return null;
11743                        }
11744                    }
11745
11746                    try {
11747                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11748                        ApplicationInfo ai =
11749                            AppGlobals.getPackageManager().
11750                                getApplicationInfo(
11751                                        cpi.applicationInfo.packageName,
11752                                        STOCK_PM_FLAGS, userId);
11753                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11754                        if (ai == null) {
11755                            Slog.w(TAG, "No package info for content provider "
11756                                    + cpi.name);
11757                            return null;
11758                        }
11759                        ai = getAppInfoForUser(ai, userId);
11760                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11761                    } catch (RemoteException ex) {
11762                        // pm is in same process, this will never happen.
11763                    } finally {
11764                        Binder.restoreCallingIdentity(ident);
11765                    }
11766                }
11767
11768                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11769
11770                if (r != null && cpr.canRunHere(r)) {
11771                    // If this is a multiprocess provider, then just return its
11772                    // info and allow the caller to instantiate it.  Only do
11773                    // this if the provider is the same user as the caller's
11774                    // process, or can run as root (so can be in any process).
11775                    return cpr.newHolder(null);
11776                }
11777
11778                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11779                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11780                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11781
11782                // This is single process, and our app is now connecting to it.
11783                // See if we are already in the process of launching this
11784                // provider.
11785                final int N = mLaunchingProviders.size();
11786                int i;
11787                for (i = 0; i < N; i++) {
11788                    if (mLaunchingProviders.get(i) == cpr) {
11789                        break;
11790                    }
11791                }
11792
11793                // If the provider is not already being launched, then get it
11794                // started.
11795                if (i >= N) {
11796                    final long origId = Binder.clearCallingIdentity();
11797
11798                    try {
11799                        // Content provider is now in use, its package can't be stopped.
11800                        try {
11801                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11802                            AppGlobals.getPackageManager().setPackageStoppedState(
11803                                    cpr.appInfo.packageName, false, userId);
11804                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11805                        } catch (RemoteException e) {
11806                        } catch (IllegalArgumentException e) {
11807                            Slog.w(TAG, "Failed trying to unstop package "
11808                                    + cpr.appInfo.packageName + ": " + e);
11809                        }
11810
11811                        // Use existing process if already started
11812                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11813                        ProcessRecord proc = getProcessRecordLocked(
11814                                cpi.processName, cpr.appInfo.uid, false);
11815                        if (proc != null && proc.thread != null && !proc.killed) {
11816                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11817                                    "Installing in existing process " + proc);
11818                            if (!proc.pubProviders.containsKey(cpi.name)) {
11819                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11820                                proc.pubProviders.put(cpi.name, cpr);
11821                                try {
11822                                    proc.thread.scheduleInstallProvider(cpi);
11823                                } catch (RemoteException e) {
11824                                }
11825                            }
11826                        } else {
11827                            checkTime(startTime, "getContentProviderImpl: before start process");
11828                            proc = startProcessLocked(cpi.processName,
11829                                    cpr.appInfo, false, 0, "content provider",
11830                                    new ComponentName(cpi.applicationInfo.packageName,
11831                                            cpi.name), false, false, false);
11832                            checkTime(startTime, "getContentProviderImpl: after start process");
11833                            if (proc == null) {
11834                                Slog.w(TAG, "Unable to launch app "
11835                                        + cpi.applicationInfo.packageName + "/"
11836                                        + cpi.applicationInfo.uid + " for provider "
11837                                        + name + ": process is bad");
11838                                return null;
11839                            }
11840                        }
11841                        cpr.launchingApp = proc;
11842                        mLaunchingProviders.add(cpr);
11843                    } finally {
11844                        Binder.restoreCallingIdentity(origId);
11845                    }
11846                }
11847
11848                checkTime(startTime, "getContentProviderImpl: updating data structures");
11849
11850                // Make sure the provider is published (the same provider class
11851                // may be published under multiple names).
11852                if (firstClass) {
11853                    mProviderMap.putProviderByClass(comp, cpr);
11854                }
11855
11856                mProviderMap.putProviderByName(name, cpr);
11857                conn = incProviderCountLocked(r, cpr, token, stable);
11858                if (conn != null) {
11859                    conn.waiting = true;
11860                }
11861            }
11862            checkTime(startTime, "getContentProviderImpl: done!");
11863
11864            grantEphemeralAccessLocked(userId, null /*intent*/,
11865                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11866        }
11867
11868        // Wait for the provider to be published...
11869        synchronized (cpr) {
11870            while (cpr.provider == null) {
11871                if (cpr.launchingApp == null) {
11872                    Slog.w(TAG, "Unable to launch app "
11873                            + cpi.applicationInfo.packageName + "/"
11874                            + cpi.applicationInfo.uid + " for provider "
11875                            + name + ": launching app became null");
11876                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11877                            UserHandle.getUserId(cpi.applicationInfo.uid),
11878                            cpi.applicationInfo.packageName,
11879                            cpi.applicationInfo.uid, name);
11880                    return null;
11881                }
11882                try {
11883                    if (DEBUG_MU) Slog.v(TAG_MU,
11884                            "Waiting to start provider " + cpr
11885                            + " launchingApp=" + cpr.launchingApp);
11886                    if (conn != null) {
11887                        conn.waiting = true;
11888                    }
11889                    cpr.wait();
11890                } catch (InterruptedException ex) {
11891                } finally {
11892                    if (conn != null) {
11893                        conn.waiting = false;
11894                    }
11895                }
11896            }
11897        }
11898        return cpr != null ? cpr.newHolder(conn) : null;
11899    }
11900
11901    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11902            ProcessRecord r, final int userId) {
11903        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11904                cpi.packageName, userId)) {
11905
11906            final boolean callerForeground = r == null || r.setSchedGroup
11907                    != ProcessList.SCHED_GROUP_BACKGROUND;
11908
11909            // Show a permission review UI only for starting from a foreground app
11910            if (!callerForeground) {
11911                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11912                        + cpi.packageName + " requires a permissions review");
11913                return false;
11914            }
11915
11916            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11917            intent.addFlags(FLAG_ACTIVITY_NEW_TASK
11918                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11919            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11920
11921            if (DEBUG_PERMISSIONS_REVIEW) {
11922                Slog.i(TAG, "u" + userId + " Launching permission review "
11923                        + "for package " + cpi.packageName);
11924            }
11925
11926            final UserHandle userHandle = new UserHandle(userId);
11927            mHandler.post(new Runnable() {
11928                @Override
11929                public void run() {
11930                    mContext.startActivityAsUser(intent, userHandle);
11931                }
11932            });
11933
11934            return false;
11935        }
11936
11937        return true;
11938    }
11939
11940    /**
11941     * Returns the PackageManager. Used by classes hosted by {@link ActivityManagerService}. The
11942     * PackageManager could be unavailable at construction time and therefore needs to be accessed
11943     * on demand.
11944     */
11945    IPackageManager getPackageManager() {
11946        return AppGlobals.getPackageManager();
11947    }
11948
11949    ActivityStartController getActivityStartController() {
11950        return mActivityStartController;
11951    }
11952
11953    PackageManagerInternal getPackageManagerInternalLocked() {
11954        if (mPackageManagerInt == null) {
11955            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11956        }
11957        return mPackageManagerInt;
11958    }
11959
11960    @Override
11961    public final ContentProviderHolder getContentProvider(
11962            IApplicationThread caller, String name, int userId, boolean stable) {
11963        enforceNotIsolatedCaller("getContentProvider");
11964        if (caller == null) {
11965            String msg = "null IApplicationThread when getting content provider "
11966                    + name;
11967            Slog.w(TAG, msg);
11968            throw new SecurityException(msg);
11969        }
11970        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11971        // with cross-user grant.
11972        return getContentProviderImpl(caller, name, null, stable, userId);
11973    }
11974
11975    public ContentProviderHolder getContentProviderExternal(
11976            String name, int userId, IBinder token) {
11977        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11978            "Do not have permission in call getContentProviderExternal()");
11979        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11980                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11981        return getContentProviderExternalUnchecked(name, token, userId);
11982    }
11983
11984    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11985            IBinder token, int userId) {
11986        return getContentProviderImpl(null, name, token, true, userId);
11987    }
11988
11989    /**
11990     * Drop a content provider from a ProcessRecord's bookkeeping
11991     */
11992    public void removeContentProvider(IBinder connection, boolean stable) {
11993        enforceNotIsolatedCaller("removeContentProvider");
11994        long ident = Binder.clearCallingIdentity();
11995        try {
11996            synchronized (this) {
11997                ContentProviderConnection conn;
11998                try {
11999                    conn = (ContentProviderConnection)connection;
12000                } catch (ClassCastException e) {
12001                    String msg ="removeContentProvider: " + connection
12002                            + " not a ContentProviderConnection";
12003                    Slog.w(TAG, msg);
12004                    throw new IllegalArgumentException(msg);
12005                }
12006                if (conn == null) {
12007                    throw new NullPointerException("connection is null");
12008                }
12009                if (decProviderCountLocked(conn, null, null, stable)) {
12010                    updateOomAdjLocked();
12011                }
12012            }
12013        } finally {
12014            Binder.restoreCallingIdentity(ident);
12015        }
12016    }
12017
12018    public void removeContentProviderExternal(String name, IBinder token) {
12019        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12020            "Do not have permission in call removeContentProviderExternal()");
12021        int userId = UserHandle.getCallingUserId();
12022        long ident = Binder.clearCallingIdentity();
12023        try {
12024            removeContentProviderExternalUnchecked(name, token, userId);
12025        } finally {
12026            Binder.restoreCallingIdentity(ident);
12027        }
12028    }
12029
12030    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
12031        synchronized (this) {
12032            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
12033            if(cpr == null) {
12034                //remove from mProvidersByClass
12035                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
12036                return;
12037            }
12038
12039            //update content provider record entry info
12040            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
12041            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
12042            if (localCpr.hasExternalProcessHandles()) {
12043                if (localCpr.removeExternalProcessHandleLocked(token)) {
12044                    updateOomAdjLocked();
12045                } else {
12046                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
12047                            + " with no external reference for token: "
12048                            + token + ".");
12049                }
12050            } else {
12051                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
12052                        + " with no external references.");
12053            }
12054        }
12055    }
12056
12057    public final void publishContentProviders(IApplicationThread caller,
12058            List<ContentProviderHolder> providers) {
12059        if (providers == null) {
12060            return;
12061        }
12062
12063        enforceNotIsolatedCaller("publishContentProviders");
12064        synchronized (this) {
12065            final ProcessRecord r = getRecordForAppLocked(caller);
12066            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
12067            if (r == null) {
12068                throw new SecurityException(
12069                        "Unable to find app for caller " + caller
12070                      + " (pid=" + Binder.getCallingPid()
12071                      + ") when publishing content providers");
12072            }
12073
12074            final long origId = Binder.clearCallingIdentity();
12075
12076            final int N = providers.size();
12077            for (int i = 0; i < N; i++) {
12078                ContentProviderHolder src = providers.get(i);
12079                if (src == null || src.info == null || src.provider == null) {
12080                    continue;
12081                }
12082                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
12083                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
12084                if (dst != null) {
12085                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
12086                    mProviderMap.putProviderByClass(comp, dst);
12087                    String names[] = dst.info.authority.split(";");
12088                    for (int j = 0; j < names.length; j++) {
12089                        mProviderMap.putProviderByName(names[j], dst);
12090                    }
12091
12092                    int launchingCount = mLaunchingProviders.size();
12093                    int j;
12094                    boolean wasInLaunchingProviders = false;
12095                    for (j = 0; j < launchingCount; j++) {
12096                        if (mLaunchingProviders.get(j) == dst) {
12097                            mLaunchingProviders.remove(j);
12098                            wasInLaunchingProviders = true;
12099                            j--;
12100                            launchingCount--;
12101                        }
12102                    }
12103                    if (wasInLaunchingProviders) {
12104                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12105                    }
12106                    synchronized (dst) {
12107                        dst.provider = src.provider;
12108                        dst.proc = r;
12109                        dst.notifyAll();
12110                    }
12111                    updateOomAdjLocked(r, true);
12112                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12113                            src.info.authority);
12114                }
12115            }
12116
12117            Binder.restoreCallingIdentity(origId);
12118        }
12119    }
12120
12121    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12122        ContentProviderConnection conn;
12123        try {
12124            conn = (ContentProviderConnection)connection;
12125        } catch (ClassCastException e) {
12126            String msg ="refContentProvider: " + connection
12127                    + " not a ContentProviderConnection";
12128            Slog.w(TAG, msg);
12129            throw new IllegalArgumentException(msg);
12130        }
12131        if (conn == null) {
12132            throw new NullPointerException("connection is null");
12133        }
12134
12135        synchronized (this) {
12136            if (stable > 0) {
12137                conn.numStableIncs += stable;
12138            }
12139            stable = conn.stableCount + stable;
12140            if (stable < 0) {
12141                throw new IllegalStateException("stableCount < 0: " + stable);
12142            }
12143
12144            if (unstable > 0) {
12145                conn.numUnstableIncs += unstable;
12146            }
12147            unstable = conn.unstableCount + unstable;
12148            if (unstable < 0) {
12149                throw new IllegalStateException("unstableCount < 0: " + unstable);
12150            }
12151
12152            if ((stable+unstable) <= 0) {
12153                throw new IllegalStateException("ref counts can't go to zero here: stable="
12154                        + stable + " unstable=" + unstable);
12155            }
12156            conn.stableCount = stable;
12157            conn.unstableCount = unstable;
12158            return !conn.dead;
12159        }
12160    }
12161
12162    public void unstableProviderDied(IBinder connection) {
12163        ContentProviderConnection conn;
12164        try {
12165            conn = (ContentProviderConnection)connection;
12166        } catch (ClassCastException e) {
12167            String msg ="refContentProvider: " + connection
12168                    + " not a ContentProviderConnection";
12169            Slog.w(TAG, msg);
12170            throw new IllegalArgumentException(msg);
12171        }
12172        if (conn == null) {
12173            throw new NullPointerException("connection is null");
12174        }
12175
12176        // Safely retrieve the content provider associated with the connection.
12177        IContentProvider provider;
12178        synchronized (this) {
12179            provider = conn.provider.provider;
12180        }
12181
12182        if (provider == null) {
12183            // Um, yeah, we're way ahead of you.
12184            return;
12185        }
12186
12187        // Make sure the caller is being honest with us.
12188        if (provider.asBinder().pingBinder()) {
12189            // Er, no, still looks good to us.
12190            synchronized (this) {
12191                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12192                        + " says " + conn + " died, but we don't agree");
12193                return;
12194            }
12195        }
12196
12197        // Well look at that!  It's dead!
12198        synchronized (this) {
12199            if (conn.provider.provider != provider) {
12200                // But something changed...  good enough.
12201                return;
12202            }
12203
12204            ProcessRecord proc = conn.provider.proc;
12205            if (proc == null || proc.thread == null) {
12206                // Seems like the process is already cleaned up.
12207                return;
12208            }
12209
12210            // As far as we're concerned, this is just like receiving a
12211            // death notification...  just a bit prematurely.
12212            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12213                    + ") early provider death");
12214            final long ident = Binder.clearCallingIdentity();
12215            try {
12216                appDiedLocked(proc);
12217            } finally {
12218                Binder.restoreCallingIdentity(ident);
12219            }
12220        }
12221    }
12222
12223    @Override
12224    public void appNotRespondingViaProvider(IBinder connection) {
12225        enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
12226
12227        final ContentProviderConnection conn = (ContentProviderConnection) connection;
12228        if (conn == null) {
12229            Slog.w(TAG, "ContentProviderConnection is null");
12230            return;
12231        }
12232
12233        final ProcessRecord host = conn.provider.proc;
12234        if (host == null) {
12235            Slog.w(TAG, "Failed to find hosting ProcessRecord");
12236            return;
12237        }
12238
12239        mHandler.post(new Runnable() {
12240            @Override
12241            public void run() {
12242                mAppErrors.appNotResponding(host, null, null, false,
12243                        "ContentProvider not responding");
12244            }
12245        });
12246    }
12247
12248    public final void installSystemProviders() {
12249        List<ProviderInfo> providers;
12250        synchronized (this) {
12251            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12252            providers = generateApplicationProvidersLocked(app);
12253            if (providers != null) {
12254                for (int i=providers.size()-1; i>=0; i--) {
12255                    ProviderInfo pi = (ProviderInfo)providers.get(i);
12256                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12257                        Slog.w(TAG, "Not installing system proc provider " + pi.name
12258                                + ": not system .apk");
12259                        providers.remove(i);
12260                    }
12261                }
12262            }
12263        }
12264        if (providers != null) {
12265            mSystemThread.installSystemProviders(providers);
12266        }
12267
12268        mConstants.start(mContext.getContentResolver());
12269        mCoreSettingsObserver = new CoreSettingsObserver(this);
12270        mFontScaleSettingObserver = new FontScaleSettingObserver();
12271        GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
12272
12273        // Now that the settings provider is published we can consider sending
12274        // in a rescue party.
12275        RescueParty.onSettingsProviderPublished(mContext);
12276
12277        //mUsageStatsService.monitorPackages();
12278    }
12279
12280    void startPersistentApps(int matchFlags) {
12281        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12282
12283        synchronized (this) {
12284            try {
12285                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12286                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12287                for (ApplicationInfo app : apps) {
12288                    if (!"android".equals(app.packageName)) {
12289                        addAppLocked(app, null, false, null /* ABI override */);
12290                    }
12291                }
12292            } catch (RemoteException ex) {
12293            }
12294        }
12295    }
12296
12297    /**
12298     * When a user is unlocked, we need to install encryption-unaware providers
12299     * belonging to any running apps.
12300     */
12301    void installEncryptionUnawareProviders(int userId) {
12302        // We're only interested in providers that are encryption unaware, and
12303        // we don't care about uninstalled apps, since there's no way they're
12304        // running at this point.
12305        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12306
12307        synchronized (this) {
12308            final int NP = mProcessNames.getMap().size();
12309            for (int ip = 0; ip < NP; ip++) {
12310                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12311                final int NA = apps.size();
12312                for (int ia = 0; ia < NA; ia++) {
12313                    final ProcessRecord app = apps.valueAt(ia);
12314                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12315
12316                    final int NG = app.pkgList.size();
12317                    for (int ig = 0; ig < NG; ig++) {
12318                        try {
12319                            final String pkgName = app.pkgList.keyAt(ig);
12320                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12321                                    .getPackageInfo(pkgName, matchFlags, userId);
12322                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12323                                for (ProviderInfo pi : pkgInfo.providers) {
12324                                    // TODO: keep in sync with generateApplicationProvidersLocked
12325                                    final boolean processMatch = Objects.equals(pi.processName,
12326                                            app.processName) || pi.multiprocess;
12327                                    final boolean userMatch = isSingleton(pi.processName,
12328                                            pi.applicationInfo, pi.name, pi.flags)
12329                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12330                                    if (processMatch && userMatch) {
12331                                        Log.v(TAG, "Installing " + pi);
12332                                        app.thread.scheduleInstallProvider(pi);
12333                                    } else {
12334                                        Log.v(TAG, "Skipping " + pi);
12335                                    }
12336                                }
12337                            }
12338                        } catch (RemoteException ignored) {
12339                        }
12340                    }
12341                }
12342            }
12343        }
12344    }
12345
12346    /**
12347     * Allows apps to retrieve the MIME type of a URI.
12348     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12349     * users, then it does not need permission to access the ContentProvider.
12350     * Either, it needs cross-user uri grants.
12351     *
12352     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12353     *
12354     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12355     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12356     */
12357    public String getProviderMimeType(Uri uri, int userId) {
12358        enforceNotIsolatedCaller("getProviderMimeType");
12359        final String name = uri.getAuthority();
12360        int callingUid = Binder.getCallingUid();
12361        int callingPid = Binder.getCallingPid();
12362        long ident = 0;
12363        boolean clearedIdentity = false;
12364        userId = mUserController.unsafeConvertIncomingUser(userId);
12365        if (canClearIdentity(callingPid, callingUid, userId)) {
12366            clearedIdentity = true;
12367            ident = Binder.clearCallingIdentity();
12368        }
12369        ContentProviderHolder holder = null;
12370        try {
12371            holder = getContentProviderExternalUnchecked(name, null, userId);
12372            if (holder != null) {
12373                return holder.provider.getType(uri);
12374            }
12375        } catch (RemoteException e) {
12376            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12377            return null;
12378        } catch (Exception e) {
12379            Log.w(TAG, "Exception while determining type of " + uri, e);
12380            return null;
12381        } finally {
12382            // We need to clear the identity to call removeContentProviderExternalUnchecked
12383            if (!clearedIdentity) {
12384                ident = Binder.clearCallingIdentity();
12385            }
12386            try {
12387                if (holder != null) {
12388                    removeContentProviderExternalUnchecked(name, null, userId);
12389                }
12390            } finally {
12391                Binder.restoreCallingIdentity(ident);
12392            }
12393        }
12394
12395        return null;
12396    }
12397
12398    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12399        if (UserHandle.getUserId(callingUid) == userId) {
12400            return true;
12401        }
12402        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12403                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12404                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12405                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12406                return true;
12407        }
12408        return false;
12409    }
12410
12411    // =========================================================
12412    // GLOBAL MANAGEMENT
12413    // =========================================================
12414
12415    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12416            boolean isolated, int isolatedUid) {
12417        String proc = customProcess != null ? customProcess : info.processName;
12418        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12419        final int userId = UserHandle.getUserId(info.uid);
12420        int uid = info.uid;
12421        if (isolated) {
12422            if (isolatedUid == 0) {
12423                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12424                while (true) {
12425                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12426                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12427                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12428                    }
12429                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12430                    mNextIsolatedProcessUid++;
12431                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12432                        // No process for this uid, use it.
12433                        break;
12434                    }
12435                    stepsLeft--;
12436                    if (stepsLeft <= 0) {
12437                        return null;
12438                    }
12439                }
12440            } else {
12441                // Special case for startIsolatedProcess (internal only), where
12442                // the uid of the isolated process is specified by the caller.
12443                uid = isolatedUid;
12444            }
12445            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12446
12447            // Register the isolated UID with this application so BatteryStats knows to
12448            // attribute resource usage to the application.
12449            //
12450            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12451            // about the process state of the isolated UID *before* it is registered with the
12452            // owning application.
12453            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12454        }
12455        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12456        if (!mBooted && !mBooting
12457                && userId == UserHandle.USER_SYSTEM
12458                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12459            r.persistent = true;
12460            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12461        }
12462        if (isolated && isolatedUid != 0) {
12463            // Special case for startIsolatedProcess (internal only) - assume the process
12464            // is required by the system server to prevent it being killed.
12465            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
12466        }
12467        addProcessNameLocked(r);
12468        return r;
12469    }
12470
12471    private boolean uidOnBackgroundWhitelist(final int uid) {
12472        final int appId = UserHandle.getAppId(uid);
12473        final int[] whitelist = mBackgroundAppIdWhitelist;
12474        final int N = whitelist.length;
12475        for (int i = 0; i < N; i++) {
12476            if (appId == whitelist[i]) {
12477                return true;
12478            }
12479        }
12480        return false;
12481    }
12482
12483    @Override
12484    public void backgroundWhitelistUid(final int uid) {
12485        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12486            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12487        }
12488
12489        if (DEBUG_BACKGROUND_CHECK) {
12490            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12491        }
12492        synchronized (this) {
12493            final int N = mBackgroundAppIdWhitelist.length;
12494            int[] newList = new int[N+1];
12495            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12496            newList[N] = UserHandle.getAppId(uid);
12497            mBackgroundAppIdWhitelist = newList;
12498        }
12499    }
12500
12501    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12502            String abiOverride) {
12503        ProcessRecord app;
12504        if (!isolated) {
12505            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12506                    info.uid, true);
12507        } else {
12508            app = null;
12509        }
12510
12511        if (app == null) {
12512            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12513            updateLruProcessLocked(app, false, null);
12514            updateOomAdjLocked();
12515        }
12516
12517        // This package really, really can not be stopped.
12518        try {
12519            AppGlobals.getPackageManager().setPackageStoppedState(
12520                    info.packageName, false, UserHandle.getUserId(app.uid));
12521        } catch (RemoteException e) {
12522        } catch (IllegalArgumentException e) {
12523            Slog.w(TAG, "Failed trying to unstop package "
12524                    + info.packageName + ": " + e);
12525        }
12526
12527        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12528            app.persistent = true;
12529            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12530        }
12531        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12532            mPersistentStartingProcesses.add(app);
12533            startProcessLocked(app, "added application",
12534                    customProcess != null ? customProcess : app.processName, abiOverride);
12535        }
12536
12537        return app;
12538    }
12539
12540    public void unhandledBack() {
12541        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12542                "unhandledBack()");
12543
12544        synchronized(this) {
12545            final long origId = Binder.clearCallingIdentity();
12546            try {
12547                getFocusedStack().unhandledBackLocked();
12548            } finally {
12549                Binder.restoreCallingIdentity(origId);
12550            }
12551        }
12552    }
12553
12554    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12555        enforceNotIsolatedCaller("openContentUri");
12556        final int userId = UserHandle.getCallingUserId();
12557        final Uri uri = Uri.parse(uriString);
12558        String name = uri.getAuthority();
12559        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12560        ParcelFileDescriptor pfd = null;
12561        if (cph != null) {
12562            // We record the binder invoker's uid in thread-local storage before
12563            // going to the content provider to open the file.  Later, in the code
12564            // that handles all permissions checks, we look for this uid and use
12565            // that rather than the Activity Manager's own uid.  The effect is that
12566            // we do the check against the caller's permissions even though it looks
12567            // to the content provider like the Activity Manager itself is making
12568            // the request.
12569            Binder token = new Binder();
12570            sCallerIdentity.set(new Identity(
12571                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12572            try {
12573                pfd = cph.provider.openFile(null, uri, "r", null, token);
12574            } catch (FileNotFoundException e) {
12575                // do nothing; pfd will be returned null
12576            } finally {
12577                // Ensure that whatever happens, we clean up the identity state
12578                sCallerIdentity.remove();
12579                // Ensure we're done with the provider.
12580                removeContentProviderExternalUnchecked(name, null, userId);
12581            }
12582        } else {
12583            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12584        }
12585        return pfd;
12586    }
12587
12588    // Actually is sleeping or shutting down or whatever else in the future
12589    // is an inactive state.
12590    boolean isSleepingOrShuttingDownLocked() {
12591        return isSleepingLocked() || mShuttingDown;
12592    }
12593
12594    boolean isShuttingDownLocked() {
12595        return mShuttingDown;
12596    }
12597
12598    boolean isSleepingLocked() {
12599        return mSleeping;
12600    }
12601
12602    void onWakefulnessChanged(int wakefulness) {
12603        synchronized(this) {
12604            boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12605            boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12606            mWakefulness = wakefulness;
12607
12608            if (wasAwake != isAwake) {
12609                // Also update state in a special way for running foreground services UI.
12610                mServices.updateScreenStateLocked(isAwake);
12611                mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
12612                        .sendToTarget();
12613            }
12614        }
12615    }
12616
12617    void finishRunningVoiceLocked() {
12618        if (mRunningVoice != null) {
12619            mRunningVoice = null;
12620            mVoiceWakeLock.release();
12621            updateSleepIfNeededLocked();
12622        }
12623    }
12624
12625    void startTimeTrackingFocusedActivityLocked() {
12626        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12627        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12628            mCurAppTimeTracker.start(resumedActivity.packageName);
12629        }
12630    }
12631
12632    void updateSleepIfNeededLocked() {
12633        final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12634        final boolean wasSleeping = mSleeping;
12635
12636        if (!shouldSleep) {
12637            // If wasSleeping is true, we need to wake up activity manager state from when
12638            // we started sleeping. In either case, we need to apply the sleep tokens, which
12639            // will wake up stacks or put them to sleep as appropriate.
12640            if (wasSleeping) {
12641                mSleeping = false;
12642                startTimeTrackingFocusedActivityLocked();
12643                mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12644                mStackSupervisor.comeOutOfSleepIfNeededLocked();
12645            }
12646            mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12647            if (wasSleeping) {
12648                updateOomAdjLocked();
12649            }
12650        } else if (!mSleeping && shouldSleep) {
12651            mSleeping = true;
12652            if (mCurAppTimeTracker != null) {
12653                mCurAppTimeTracker.stop();
12654            }
12655            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12656            mStackSupervisor.goingToSleepLocked();
12657            updateOomAdjLocked();
12658        }
12659    }
12660
12661    /** Pokes the task persister. */
12662    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12663        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12664    }
12665
12666    /**
12667     * Notifies all listeners when the pinned stack animation starts.
12668     */
12669    @Override
12670    public void notifyPinnedStackAnimationStarted() {
12671        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12672    }
12673
12674    /**
12675     * Notifies all listeners when the pinned stack animation ends.
12676     */
12677    @Override
12678    public void notifyPinnedStackAnimationEnded() {
12679        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12680    }
12681
12682    @Override
12683    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12684        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12685    }
12686
12687    @Override
12688    public boolean shutdown(int timeout) {
12689        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12690                != PackageManager.PERMISSION_GRANTED) {
12691            throw new SecurityException("Requires permission "
12692                    + android.Manifest.permission.SHUTDOWN);
12693        }
12694
12695        // TODO: Where should the corresponding '1' (start) write go?
12696        StatsLog.write(StatsLog.DEVICE_ON_STATUS_CHANGED, 0);
12697
12698        boolean timedout = false;
12699
12700        synchronized(this) {
12701            mShuttingDown = true;
12702            mStackSupervisor.prepareForShutdownLocked();
12703            updateEventDispatchingLocked();
12704            timedout = mStackSupervisor.shutdownLocked(timeout);
12705        }
12706
12707        mAppOpsService.shutdown();
12708        if (mUsageStatsService != null) {
12709            mUsageStatsService.prepareShutdown();
12710        }
12711        mBatteryStatsService.shutdown();
12712        synchronized (this) {
12713            mProcessStats.shutdownLocked();
12714            notifyTaskPersisterLocked(null, true);
12715        }
12716
12717        return timedout;
12718    }
12719
12720    public final void activitySlept(IBinder token) {
12721        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12722
12723        final long origId = Binder.clearCallingIdentity();
12724
12725        synchronized (this) {
12726            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12727            if (r != null) {
12728                mStackSupervisor.activitySleptLocked(r);
12729            }
12730        }
12731
12732        Binder.restoreCallingIdentity(origId);
12733    }
12734
12735    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12736        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12737        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12738        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12739            boolean wasRunningVoice = mRunningVoice != null;
12740            mRunningVoice = session;
12741            if (!wasRunningVoice) {
12742                mVoiceWakeLock.acquire();
12743                updateSleepIfNeededLocked();
12744            }
12745        }
12746    }
12747
12748    private void updateEventDispatchingLocked() {
12749        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12750    }
12751
12752    @Override
12753    public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12754        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12755                != PackageManager.PERMISSION_GRANTED) {
12756            throw new SecurityException("Requires permission "
12757                    + android.Manifest.permission.DEVICE_POWER);
12758        }
12759
12760        synchronized(this) {
12761            long ident = Binder.clearCallingIdentity();
12762            try {
12763                mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12764            } finally {
12765                Binder.restoreCallingIdentity(ident);
12766            }
12767        }
12768
12769        mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
12770                .sendToTarget();
12771    }
12772
12773    @Override
12774    public void notifyLockedProfile(@UserIdInt int userId) {
12775        try {
12776            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12777                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12778            }
12779        } catch (RemoteException ex) {
12780            throw new SecurityException("Fail to check is caller a privileged app", ex);
12781        }
12782
12783        synchronized (this) {
12784            final long ident = Binder.clearCallingIdentity();
12785            try {
12786                if (mUserController.shouldConfirmCredentials(userId)) {
12787                    if (mKeyguardController.isKeyguardLocked()) {
12788                        // Showing launcher to avoid user entering credential twice.
12789                        final int currentUserId = mUserController.getCurrentUserId();
12790                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12791                    }
12792                    mStackSupervisor.lockAllProfileTasks(userId);
12793                }
12794            } finally {
12795                Binder.restoreCallingIdentity(ident);
12796            }
12797        }
12798    }
12799
12800    @Override
12801    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12802        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12803        synchronized (this) {
12804            final long ident = Binder.clearCallingIdentity();
12805            try {
12806                intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
12807                        FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
12808                        FLAG_ACTIVITY_TASK_ON_HOME);
12809                ActivityOptions activityOptions = options != null
12810                        ? new ActivityOptions(options)
12811                        : ActivityOptions.makeBasic();
12812                activityOptions.setLaunchTaskId(
12813                        mStackSupervisor.getHomeActivity().getTask().taskId);
12814                mContext.startActivityAsUser(intent, activityOptions.toBundle(),
12815                        UserHandle.CURRENT);
12816            } finally {
12817                Binder.restoreCallingIdentity(ident);
12818            }
12819        }
12820    }
12821
12822    @Override
12823    public void stopAppSwitches() {
12824        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12825                != PackageManager.PERMISSION_GRANTED) {
12826            throw new SecurityException("viewquires permission "
12827                    + android.Manifest.permission.STOP_APP_SWITCHES);
12828        }
12829
12830        synchronized(this) {
12831            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12832                    + APP_SWITCH_DELAY_TIME;
12833            mDidAppSwitch = false;
12834            mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
12835        }
12836    }
12837
12838    public void resumeAppSwitches() {
12839        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12840                != PackageManager.PERMISSION_GRANTED) {
12841            throw new SecurityException("Requires permission "
12842                    + android.Manifest.permission.STOP_APP_SWITCHES);
12843        }
12844
12845        synchronized(this) {
12846            // Note that we don't execute any pending app switches... we will
12847            // let those wait until either the timeout, or the next start
12848            // activity request.
12849            mAppSwitchesAllowedTime = 0;
12850        }
12851    }
12852
12853    boolean checkAllowAppSwitchUid(int uid) {
12854        ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
12855        if (types != null) {
12856            for (int i = types.size() - 1; i >= 0; i--) {
12857                if (types.valueAt(i).intValue() == uid) {
12858                    return true;
12859                }
12860            }
12861        }
12862        return false;
12863    }
12864
12865    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12866            int callingPid, int callingUid, String name) {
12867        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12868            return true;
12869        }
12870
12871        int perm = checkComponentPermission(
12872                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12873                sourceUid, -1, true);
12874        if (perm == PackageManager.PERMISSION_GRANTED) {
12875            return true;
12876        }
12877        if (checkAllowAppSwitchUid(sourceUid)) {
12878            return true;
12879        }
12880
12881        // If the actual IPC caller is different from the logical source, then
12882        // also see if they are allowed to control app switches.
12883        if (callingUid != -1 && callingUid != sourceUid) {
12884            perm = checkComponentPermission(
12885                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12886                    callingUid, -1, true);
12887            if (perm == PackageManager.PERMISSION_GRANTED) {
12888                return true;
12889            }
12890            if (checkAllowAppSwitchUid(callingUid)) {
12891                return true;
12892            }
12893        }
12894
12895        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12896        return false;
12897    }
12898
12899    public void setDebugApp(String packageName, boolean waitForDebugger,
12900            boolean persistent) {
12901        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12902                "setDebugApp()");
12903
12904        long ident = Binder.clearCallingIdentity();
12905        try {
12906            // Note that this is not really thread safe if there are multiple
12907            // callers into it at the same time, but that's not a situation we
12908            // care about.
12909            if (persistent) {
12910                final ContentResolver resolver = mContext.getContentResolver();
12911                Settings.Global.putString(
12912                    resolver, Settings.Global.DEBUG_APP,
12913                    packageName);
12914                Settings.Global.putInt(
12915                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12916                    waitForDebugger ? 1 : 0);
12917            }
12918
12919            synchronized (this) {
12920                if (!persistent) {
12921                    mOrigDebugApp = mDebugApp;
12922                    mOrigWaitForDebugger = mWaitForDebugger;
12923                }
12924                mDebugApp = packageName;
12925                mWaitForDebugger = waitForDebugger;
12926                mDebugTransient = !persistent;
12927                if (packageName != null) {
12928                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12929                            false, UserHandle.USER_ALL, "set debug app");
12930                }
12931            }
12932        } finally {
12933            Binder.restoreCallingIdentity(ident);
12934        }
12935    }
12936
12937    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12938        synchronized (this) {
12939            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12940            if (!isDebuggable) {
12941                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12942                    throw new SecurityException("Process not debuggable: " + app.packageName);
12943                }
12944            }
12945
12946            mTrackAllocationApp = processName;
12947        }
12948    }
12949
12950    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12951        synchronized (this) {
12952            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12953            if (!isDebuggable) {
12954                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12955                    throw new SecurityException("Process not debuggable: " + app.packageName);
12956                }
12957            }
12958            mProfileApp = processName;
12959
12960            if (mProfilerInfo != null) {
12961                if (mProfilerInfo.profileFd != null) {
12962                    try {
12963                        mProfilerInfo.profileFd.close();
12964                    } catch (IOException e) {
12965                    }
12966                }
12967            }
12968            mProfilerInfo = new ProfilerInfo(profilerInfo);
12969            mProfileType = 0;
12970        }
12971    }
12972
12973    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12974        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12975        if (!isDebuggable) {
12976            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12977                throw new SecurityException("Process not debuggable: " + app.packageName);
12978            }
12979        }
12980        mNativeDebuggingApp = processName;
12981    }
12982
12983    @Override
12984    public void setAlwaysFinish(boolean enabled) {
12985        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12986                "setAlwaysFinish()");
12987
12988        long ident = Binder.clearCallingIdentity();
12989        try {
12990            Settings.Global.putInt(
12991                    mContext.getContentResolver(),
12992                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12993
12994            synchronized (this) {
12995                mAlwaysFinishActivities = enabled;
12996            }
12997        } finally {
12998            Binder.restoreCallingIdentity(ident);
12999        }
13000    }
13001
13002    @Override
13003    public void setActivityController(IActivityController controller, boolean imAMonkey) {
13004        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13005                "setActivityController()");
13006        synchronized (this) {
13007            mController = controller;
13008            mControllerIsAMonkey = imAMonkey;
13009            Watchdog.getInstance().setActivityController(controller);
13010        }
13011    }
13012
13013    @Override
13014    public void setUserIsMonkey(boolean userIsMonkey) {
13015        synchronized (this) {
13016            synchronized (mPidsSelfLocked) {
13017                final int callingPid = Binder.getCallingPid();
13018                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
13019                if (proc == null) {
13020                    throw new SecurityException("Unknown process: " + callingPid);
13021                }
13022                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
13023                    throw new SecurityException("Only an instrumentation process "
13024                            + "with a UiAutomation can call setUserIsMonkey");
13025                }
13026            }
13027            mUserIsMonkey = userIsMonkey;
13028        }
13029    }
13030
13031    @Override
13032    public boolean isUserAMonkey() {
13033        synchronized (this) {
13034            // If there is a controller also implies the user is a monkey.
13035            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
13036        }
13037    }
13038
13039    /**
13040     * @deprecated This method is only used by a few internal components and it will soon be
13041     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13042     * No new code should be calling it.
13043     */
13044    @Deprecated
13045    @Override
13046    public void requestBugReport(int bugreportType) {
13047        String extraOptions = null;
13048        switch (bugreportType) {
13049            case ActivityManager.BUGREPORT_OPTION_FULL:
13050                // Default options.
13051                break;
13052            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
13053                extraOptions = "bugreportplus";
13054                break;
13055            case ActivityManager.BUGREPORT_OPTION_REMOTE:
13056                extraOptions = "bugreportremote";
13057                break;
13058            case ActivityManager.BUGREPORT_OPTION_WEAR:
13059                extraOptions = "bugreportwear";
13060                break;
13061            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
13062                extraOptions = "bugreporttelephony";
13063                break;
13064            default:
13065                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
13066                        + bugreportType);
13067        }
13068        // Always log caller, even if it does not have permission to dump.
13069        String type = extraOptions == null ? "bugreport" : extraOptions;
13070        Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
13071
13072        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13073        if (extraOptions != null) {
13074            SystemProperties.set("dumpstate.options", extraOptions);
13075        }
13076        SystemProperties.set("ctl.start", "bugreport");
13077    }
13078
13079    /**
13080     * @deprecated This method is only used by a few internal components and it will soon be
13081     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13082     * No new code should be calling it.
13083     */
13084    @Deprecated
13085    @Override
13086    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13087
13088        if (!TextUtils.isEmpty(shareTitle)) {
13089            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13090                String errorStr = "shareTitle should be less than " +
13091                        MAX_BUGREPORT_TITLE_SIZE + " characters";
13092                throw new IllegalArgumentException(errorStr);
13093            } else {
13094                if (!TextUtils.isEmpty(shareDescription)) {
13095                    int length;
13096                    try {
13097                        length = shareDescription.getBytes("UTF-8").length;
13098                    } catch (UnsupportedEncodingException e) {
13099                        String errorStr = "shareDescription: UnsupportedEncodingException";
13100                        throw new IllegalArgumentException(errorStr);
13101                    }
13102                    if (length > SystemProperties.PROP_VALUE_MAX) {
13103                        String errorStr = "shareTitle should be less than " +
13104                                SystemProperties.PROP_VALUE_MAX + " bytes";
13105                        throw new IllegalArgumentException(errorStr);
13106                    } else {
13107                        SystemProperties.set("dumpstate.options.description", shareDescription);
13108                    }
13109                }
13110                SystemProperties.set("dumpstate.options.title", shareTitle);
13111            }
13112        }
13113
13114        Slog.d(TAG, "Bugreport notification title " + shareTitle
13115                + " description " + shareDescription);
13116        requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13117    }
13118
13119    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13120        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13121    }
13122
13123    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13124        if (r != null && (r.instr != null || r.usingWrapper)) {
13125            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13126        }
13127        return KEY_DISPATCHING_TIMEOUT;
13128    }
13129
13130    @Override
13131    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13132        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13133                != PackageManager.PERMISSION_GRANTED) {
13134            throw new SecurityException("Requires permission "
13135                    + android.Manifest.permission.FILTER_EVENTS);
13136        }
13137        ProcessRecord proc;
13138        long timeout;
13139        synchronized (this) {
13140            synchronized (mPidsSelfLocked) {
13141                proc = mPidsSelfLocked.get(pid);
13142            }
13143            timeout = getInputDispatchingTimeoutLocked(proc);
13144        }
13145
13146        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13147            return -1;
13148        }
13149
13150        return timeout;
13151    }
13152
13153    /**
13154     * Handle input dispatching timeouts.
13155     * Returns whether input dispatching should be aborted or not.
13156     */
13157    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13158            final ActivityRecord activity, final ActivityRecord parent,
13159            final boolean aboveSystem, String reason) {
13160        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13161                != PackageManager.PERMISSION_GRANTED) {
13162            throw new SecurityException("Requires permission "
13163                    + android.Manifest.permission.FILTER_EVENTS);
13164        }
13165
13166        final String annotation;
13167        if (reason == null) {
13168            annotation = "Input dispatching timed out";
13169        } else {
13170            annotation = "Input dispatching timed out (" + reason + ")";
13171        }
13172
13173        if (proc != null) {
13174            synchronized (this) {
13175                if (proc.debugging) {
13176                    return false;
13177                }
13178
13179                if (proc.instr != null) {
13180                    Bundle info = new Bundle();
13181                    info.putString("shortMsg", "keyDispatchingTimedOut");
13182                    info.putString("longMsg", annotation);
13183                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13184                    return true;
13185                }
13186            }
13187            mHandler.post(new Runnable() {
13188                @Override
13189                public void run() {
13190                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13191                }
13192            });
13193        }
13194
13195        return true;
13196    }
13197
13198    @Override
13199    public Bundle getAssistContextExtras(int requestType) {
13200        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13201                null, null, true /* focused */, true /* newSessionId */,
13202                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13203        if (pae == null) {
13204            return null;
13205        }
13206        synchronized (pae) {
13207            while (!pae.haveResult) {
13208                try {
13209                    pae.wait();
13210                } catch (InterruptedException e) {
13211                }
13212            }
13213        }
13214        synchronized (this) {
13215            buildAssistBundleLocked(pae, pae.result);
13216            mPendingAssistExtras.remove(pae);
13217            mUiHandler.removeCallbacks(pae);
13218        }
13219        return pae.extras;
13220    }
13221
13222    @Override
13223    public boolean isAssistDataAllowedOnCurrentActivity() {
13224        int userId;
13225        synchronized (this) {
13226            final ActivityStack focusedStack = getFocusedStack();
13227            if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
13228                return false;
13229            }
13230
13231            final ActivityRecord activity = focusedStack.getTopActivity();
13232            if (activity == null) {
13233                return false;
13234            }
13235            userId = activity.userId;
13236        }
13237        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13238                Context.DEVICE_POLICY_SERVICE);
13239        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13240    }
13241
13242    @Override
13243    public boolean showAssistFromActivity(IBinder token, Bundle args) {
13244        long ident = Binder.clearCallingIdentity();
13245        try {
13246            synchronized (this) {
13247                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13248                ActivityRecord top = getFocusedStack().getTopActivity();
13249                if (top != caller) {
13250                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13251                            + " is not current top " + top);
13252                    return false;
13253                }
13254                if (!top.nowVisible) {
13255                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13256                            + " is not visible");
13257                    return false;
13258                }
13259            }
13260            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13261                    token);
13262        } finally {
13263            Binder.restoreCallingIdentity(ident);
13264        }
13265    }
13266
13267    @Override
13268    public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
13269            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13270        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13271                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13272                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13273    }
13274
13275    @Override
13276    public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
13277            IBinder activityToken, int flags) {
13278        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13279                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13280                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13281    }
13282
13283    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13284            IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13285            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13286            int flags) {
13287        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13288                "enqueueAssistContext()");
13289
13290        synchronized (this) {
13291            ActivityRecord activity = getFocusedStack().getTopActivity();
13292            if (activity == null) {
13293                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13294                return null;
13295            }
13296            if (activity.app == null || activity.app.thread == null) {
13297                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13298                return null;
13299            }
13300            if (focused) {
13301                if (activityToken != null) {
13302                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13303                    if (activity != caller) {
13304                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13305                                + " is not current top " + activity);
13306                        return null;
13307                    }
13308                }
13309            } else {
13310                activity = ActivityRecord.forTokenLocked(activityToken);
13311                if (activity == null) {
13312                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13313                            + " couldn't be found");
13314                    return null;
13315                }
13316                if (activity.app == null || activity.app.thread == null) {
13317                    Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13318                    return null;
13319                }
13320            }
13321
13322            PendingAssistExtras pae;
13323            Bundle extras = new Bundle();
13324            if (args != null) {
13325                extras.putAll(args);
13326            }
13327            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13328            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13329
13330            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13331                    userHandle);
13332            pae.isHome = activity.isActivityTypeHome();
13333
13334            // Increment the sessionId if necessary
13335            if (newSessionId) {
13336                mViSessionId++;
13337            }
13338            try {
13339                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13340                        mViSessionId, flags);
13341                mPendingAssistExtras.add(pae);
13342                mUiHandler.postDelayed(pae, timeout);
13343            } catch (RemoteException e) {
13344                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13345                return null;
13346            }
13347            return pae;
13348        }
13349    }
13350
13351    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13352        IAssistDataReceiver receiver;
13353        synchronized (this) {
13354            mPendingAssistExtras.remove(pae);
13355            receiver = pae.receiver;
13356        }
13357        if (receiver != null) {
13358            // Caller wants result sent back to them.
13359            Bundle sendBundle = new Bundle();
13360            // At least return the receiver extras
13361            sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13362            try {
13363                pae.receiver.onHandleAssistData(sendBundle);
13364            } catch (RemoteException e) {
13365            }
13366        }
13367    }
13368
13369    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13370        if (result != null) {
13371            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13372        }
13373        if (pae.hint != null) {
13374            pae.extras.putBoolean(pae.hint, true);
13375        }
13376    }
13377
13378    /** Called from an app when assist data is ready. */
13379    @Override
13380    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13381            AssistContent content, Uri referrer) {
13382        PendingAssistExtras pae = (PendingAssistExtras)token;
13383        synchronized (pae) {
13384            pae.result = extras;
13385            pae.structure = structure;
13386            pae.content = content;
13387            if (referrer != null) {
13388                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13389            }
13390            if (structure != null) {
13391                structure.setHomeActivity(pae.isHome);
13392            }
13393            pae.haveResult = true;
13394            pae.notifyAll();
13395            if (pae.intent == null && pae.receiver == null) {
13396                // Caller is just waiting for the result.
13397                return;
13398            }
13399        }
13400        // We are now ready to launch the assist activity.
13401        IAssistDataReceiver sendReceiver = null;
13402        Bundle sendBundle = null;
13403        synchronized (this) {
13404            buildAssistBundleLocked(pae, extras);
13405            boolean exists = mPendingAssistExtras.remove(pae);
13406            mUiHandler.removeCallbacks(pae);
13407            if (!exists) {
13408                // Timed out.
13409                return;
13410            }
13411            if ((sendReceiver=pae.receiver) != null) {
13412                // Caller wants result sent back to them.
13413                sendBundle = new Bundle();
13414                sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
13415                sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
13416                sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
13417                sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13418            }
13419        }
13420        if (sendReceiver != null) {
13421            try {
13422                sendReceiver.onHandleAssistData(sendBundle);
13423            } catch (RemoteException e) {
13424            }
13425            return;
13426        }
13427
13428        final long ident = Binder.clearCallingIdentity();
13429        try {
13430            if (TextUtils.equals(pae.intent.getAction(),
13431                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13432                pae.intent.putExtras(pae.extras);
13433                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13434            } else {
13435                pae.intent.replaceExtras(pae.extras);
13436                pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
13437                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
13438                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13439                closeSystemDialogs("assist");
13440
13441                try {
13442                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13443                } catch (ActivityNotFoundException e) {
13444                    Slog.w(TAG, "No activity to handle assist action.", e);
13445                }
13446            }
13447        } finally {
13448            Binder.restoreCallingIdentity(ident);
13449        }
13450    }
13451
13452    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13453            Bundle args) {
13454        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13455                true /* focused */, true /* newSessionId */, userHandle, args,
13456                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13457    }
13458
13459    public void registerProcessObserver(IProcessObserver observer) {
13460        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13461                "registerProcessObserver()");
13462        synchronized (this) {
13463            mProcessObservers.register(observer);
13464        }
13465    }
13466
13467    @Override
13468    public void unregisterProcessObserver(IProcessObserver observer) {
13469        synchronized (this) {
13470            mProcessObservers.unregister(observer);
13471        }
13472    }
13473
13474    @Override
13475    public int getUidProcessState(int uid, String callingPackage) {
13476        if (!hasUsageStatsPermission(callingPackage)) {
13477            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13478                    "getUidProcessState");
13479        }
13480
13481        synchronized (this) {
13482            UidRecord uidRec = mActiveUids.get(uid);
13483            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13484        }
13485    }
13486
13487    @Override
13488    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13489            String callingPackage) {
13490        if (!hasUsageStatsPermission(callingPackage)) {
13491            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13492                    "registerUidObserver");
13493        }
13494        synchronized (this) {
13495            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13496                    callingPackage, which, cutpoint));
13497        }
13498    }
13499
13500    @Override
13501    public void unregisterUidObserver(IUidObserver observer) {
13502        synchronized (this) {
13503            mUidObservers.unregister(observer);
13504        }
13505    }
13506
13507    @Override
13508    public boolean convertFromTranslucent(IBinder token) {
13509        final long origId = Binder.clearCallingIdentity();
13510        try {
13511            synchronized (this) {
13512                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13513                if (r == null) {
13514                    return false;
13515                }
13516                final boolean translucentChanged = r.changeWindowTranslucency(true);
13517                if (translucentChanged) {
13518                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13519                }
13520                mWindowManager.setAppFullscreen(token, true);
13521                return translucentChanged;
13522            }
13523        } finally {
13524            Binder.restoreCallingIdentity(origId);
13525        }
13526    }
13527
13528    @Override
13529    public boolean convertToTranslucent(IBinder token, Bundle options) {
13530        final long origId = Binder.clearCallingIdentity();
13531        try {
13532            synchronized (this) {
13533                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13534                if (r == null) {
13535                    return false;
13536                }
13537                final TaskRecord task = r.getTask();
13538                int index = task.mActivities.lastIndexOf(r);
13539                if (index > 0) {
13540                    ActivityRecord under = task.mActivities.get(index - 1);
13541                    under.returningOptions = ActivityOptions.fromBundle(options);
13542                }
13543                final boolean translucentChanged = r.changeWindowTranslucency(false);
13544                if (translucentChanged) {
13545                    r.getStack().convertActivityToTranslucent(r);
13546                }
13547                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13548                mWindowManager.setAppFullscreen(token, false);
13549                return translucentChanged;
13550            }
13551        } finally {
13552            Binder.restoreCallingIdentity(origId);
13553        }
13554    }
13555
13556    @Override
13557    public Bundle getActivityOptions(IBinder token) {
13558        final long origId = Binder.clearCallingIdentity();
13559        try {
13560            synchronized (this) {
13561                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13562                if (r != null) {
13563                    final ActivityOptions activityOptions = r.takeOptionsLocked();
13564                    return activityOptions == null ? null : activityOptions.toBundle();
13565                }
13566                return null;
13567            }
13568        } finally {
13569            Binder.restoreCallingIdentity(origId);
13570        }
13571    }
13572
13573    @Override
13574    public void setImmersive(IBinder token, boolean immersive) {
13575        synchronized(this) {
13576            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13577            if (r == null) {
13578                throw new IllegalArgumentException();
13579            }
13580            r.immersive = immersive;
13581
13582            // update associated state if we're frontmost
13583            if (r == mStackSupervisor.getResumedActivityLocked()) {
13584                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13585                applyUpdateLockStateLocked(r);
13586            }
13587        }
13588    }
13589
13590    @Override
13591    public boolean isImmersive(IBinder token) {
13592        synchronized (this) {
13593            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13594            if (r == null) {
13595                throw new IllegalArgumentException();
13596            }
13597            return r.immersive;
13598        }
13599    }
13600
13601    @Override
13602    public void setVrThread(int tid) {
13603        enforceSystemHasVrFeature();
13604        synchronized (this) {
13605            synchronized (mPidsSelfLocked) {
13606                final int pid = Binder.getCallingPid();
13607                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13608                mVrController.setVrThreadLocked(tid, pid, proc);
13609            }
13610        }
13611    }
13612
13613    @Override
13614    public void setPersistentVrThread(int tid) {
13615        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13616            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13617                    + Binder.getCallingPid()
13618                    + ", uid=" + Binder.getCallingUid()
13619                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13620            Slog.w(TAG, msg);
13621            throw new SecurityException(msg);
13622        }
13623        enforceSystemHasVrFeature();
13624        synchronized (this) {
13625            synchronized (mPidsSelfLocked) {
13626                final int pid = Binder.getCallingPid();
13627                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13628                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13629            }
13630        }
13631    }
13632
13633    /**
13634     * Schedule the given thread a normal scheduling priority.
13635     *
13636     * @param tid the tid of the thread to adjust the scheduling of.
13637     * @param suppressLogs {@code true} if any error logging should be disabled.
13638     *
13639     * @return {@code true} if this succeeded.
13640     */
13641    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13642        try {
13643            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13644            return true;
13645        } catch (IllegalArgumentException e) {
13646            if (!suppressLogs) {
13647                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13648            }
13649        } catch (SecurityException e) {
13650            if (!suppressLogs) {
13651                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13652            }
13653        }
13654        return false;
13655    }
13656
13657    /**
13658     * Schedule the given thread an FIFO scheduling priority.
13659     *
13660     * @param tid the tid of the thread to adjust the scheduling of.
13661     * @param suppressLogs {@code true} if any error logging should be disabled.
13662     *
13663     * @return {@code true} if this succeeded.
13664     */
13665    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13666        try {
13667            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13668            return true;
13669        } catch (IllegalArgumentException e) {
13670            if (!suppressLogs) {
13671                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13672            }
13673        } catch (SecurityException e) {
13674            if (!suppressLogs) {
13675                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13676            }
13677        }
13678        return false;
13679    }
13680
13681    /**
13682     * Check that we have the features required for VR-related API calls, and throw an exception if
13683     * not.
13684     */
13685    private void enforceSystemHasVrFeature() {
13686        if (!mContext.getPackageManager().hasSystemFeature(
13687                PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
13688            throw new UnsupportedOperationException("VR mode not supported on this device!");
13689        }
13690    }
13691
13692    @Override
13693    public void setRenderThread(int tid) {
13694        synchronized (this) {
13695            ProcessRecord proc;
13696            int pid = Binder.getCallingPid();
13697            if (pid == Process.myPid()) {
13698                demoteSystemServerRenderThread(tid);
13699                return;
13700            }
13701            synchronized (mPidsSelfLocked) {
13702                proc = mPidsSelfLocked.get(pid);
13703                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13704                    // ensure the tid belongs to the process
13705                    if (!isThreadInProcess(pid, tid)) {
13706                        throw new IllegalArgumentException(
13707                            "Render thread does not belong to process");
13708                    }
13709                    proc.renderThreadTid = tid;
13710                    if (DEBUG_OOM_ADJ) {
13711                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13712                    }
13713                    // promote to FIFO now
13714                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13715                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13716                        if (mUseFifoUiScheduling) {
13717                            setThreadScheduler(proc.renderThreadTid,
13718                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13719                        } else {
13720                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13721                        }
13722                    }
13723                } else {
13724                    if (DEBUG_OOM_ADJ) {
13725                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13726                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13727                               mUseFifoUiScheduling);
13728                    }
13729                }
13730            }
13731        }
13732    }
13733
13734    /**
13735     * We only use RenderThread in system_server to store task snapshots to the disk, which should
13736     * happen in the background. Thus, demote render thread from system_server to a lower priority.
13737     *
13738     * @param tid the tid of the RenderThread
13739     */
13740    private void demoteSystemServerRenderThread(int tid) {
13741        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13742    }
13743
13744    @Override
13745    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13746        enforceSystemHasVrFeature();
13747
13748        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13749
13750        ActivityRecord r;
13751        synchronized (this) {
13752            r = ActivityRecord.isInStackLocked(token);
13753        }
13754
13755        if (r == null) {
13756            throw new IllegalArgumentException();
13757        }
13758
13759        int err;
13760        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13761                VrManagerInternal.NO_ERROR) {
13762            return err;
13763        }
13764
13765        synchronized(this) {
13766            r.requestedVrComponent = (enabled) ? packageName : null;
13767
13768            // Update associated state if this activity is currently focused
13769            if (r == mStackSupervisor.getResumedActivityLocked()) {
13770                applyUpdateVrModeLocked(r);
13771            }
13772            return 0;
13773        }
13774    }
13775
13776    @Override
13777    public boolean isVrModePackageEnabled(ComponentName packageName) {
13778        enforceSystemHasVrFeature();
13779
13780        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13781
13782        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13783                VrManagerInternal.NO_ERROR;
13784    }
13785
13786    public boolean isTopActivityImmersive() {
13787        enforceNotIsolatedCaller("startActivity");
13788        synchronized (this) {
13789            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13790            return (r != null) ? r.immersive : false;
13791        }
13792    }
13793
13794    /**
13795     * @return whether the system should disable UI modes incompatible with VR mode.
13796     */
13797    boolean shouldDisableNonVrUiLocked() {
13798        return mVrController.shouldDisableNonVrUiLocked();
13799    }
13800
13801    @Override
13802    public boolean isTopOfTask(IBinder token) {
13803        synchronized (this) {
13804            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13805            if (r == null) {
13806                throw new IllegalArgumentException();
13807            }
13808            return r.getTask().getTopActivity() == r;
13809        }
13810    }
13811
13812    @Override
13813    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13814        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13815            String msg = "Permission Denial: setHasTopUi() from pid="
13816                    + Binder.getCallingPid()
13817                    + ", uid=" + Binder.getCallingUid()
13818                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13819            Slog.w(TAG, msg);
13820            throw new SecurityException(msg);
13821        }
13822        final int pid = Binder.getCallingPid();
13823        final long origId = Binder.clearCallingIdentity();
13824        try {
13825            synchronized (this) {
13826                boolean changed = false;
13827                ProcessRecord pr;
13828                synchronized (mPidsSelfLocked) {
13829                    pr = mPidsSelfLocked.get(pid);
13830                    if (pr == null) {
13831                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13832                        return;
13833                    }
13834                    if (pr.hasTopUi != hasTopUi) {
13835                        if (DEBUG_OOM_ADJ) {
13836                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13837                        }
13838                        pr.hasTopUi = hasTopUi;
13839                        changed = true;
13840                    }
13841                }
13842                if (changed) {
13843                    updateOomAdjLocked(pr, true);
13844                }
13845            }
13846        } finally {
13847            Binder.restoreCallingIdentity(origId);
13848        }
13849    }
13850
13851    public final void enterSafeMode() {
13852        synchronized(this) {
13853            // It only makes sense to do this before the system is ready
13854            // and started launching other packages.
13855            if (!mSystemReady) {
13856                try {
13857                    AppGlobals.getPackageManager().enterSafeMode();
13858                } catch (RemoteException e) {
13859                }
13860            }
13861
13862            mSafeMode = true;
13863        }
13864    }
13865
13866    public final void showSafeModeOverlay() {
13867        View v = LayoutInflater.from(mContext).inflate(
13868                com.android.internal.R.layout.safe_mode, null);
13869        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13870        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13871        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13872        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13873        lp.gravity = Gravity.BOTTOM | Gravity.START;
13874        lp.format = v.getBackground().getOpacity();
13875        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13876                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13877        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13878        ((WindowManager)mContext.getSystemService(
13879                Context.WINDOW_SERVICE)).addView(v, lp);
13880    }
13881
13882    @Override
13883    public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
13884            String sourcePkg, String tag) {
13885        if (workSource != null && workSource.isEmpty()) {
13886            workSource = null;
13887        }
13888
13889        if (sourceUid <= 0 && workSource == null) {
13890            // Try and derive a UID to attribute things to based on the caller.
13891            if (sender != null) {
13892                if (!(sender instanceof PendingIntentRecord)) {
13893                    return;
13894                }
13895
13896                final PendingIntentRecord rec = (PendingIntentRecord) sender;
13897                final int callerUid = Binder.getCallingUid();
13898                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
13899            } else {
13900                // TODO(narayan): Should we throw an exception in this case ? It means that we
13901                // haven't been able to derive a UID to attribute things to.
13902                return;
13903            }
13904        }
13905
13906        if (DEBUG_POWER) {
13907            Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
13908                    + ", workSource=" + workSource + ", tag=" + tag + "]");
13909        }
13910
13911        mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
13912    }
13913
13914    @Override
13915    public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
13916            String tag) {
13917        if (workSource != null && workSource.isEmpty()) {
13918            workSource = null;
13919        }
13920
13921        if (sourceUid <= 0 && workSource == null) {
13922            // Try and derive a UID to attribute things to based on the caller.
13923            if (sender != null) {
13924                if (!(sender instanceof PendingIntentRecord)) {
13925                    return;
13926                }
13927
13928                final PendingIntentRecord rec = (PendingIntentRecord) sender;
13929                final int callerUid = Binder.getCallingUid();
13930                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
13931            } else {
13932                // TODO(narayan): Should we throw an exception in this case ? It means that we
13933                // haven't been able to derive a UID to attribute things to.
13934                return;
13935            }
13936        }
13937
13938        if (DEBUG_POWER) {
13939            Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
13940                    ", tag=" + tag + "]");
13941        }
13942
13943        mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
13944    }
13945
13946    @Override
13947    public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
13948            String tag) {
13949        if (workSource != null && workSource.isEmpty()) {
13950            workSource = null;
13951        }
13952
13953        if (sourceUid <= 0 && workSource == null) {
13954            // Try and derive a UID to attribute things to based on the caller.
13955            if (sender != null) {
13956                if (!(sender instanceof PendingIntentRecord)) {
13957                    return;
13958                }
13959
13960                final PendingIntentRecord rec = (PendingIntentRecord) sender;
13961                final int callerUid = Binder.getCallingUid();
13962                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
13963            } else {
13964                // TODO(narayan): Should we throw an exception in this case ? It means that we
13965                // haven't been able to derive a UID to attribute things to.
13966                return;
13967            }
13968        }
13969
13970        if (DEBUG_POWER) {
13971            Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
13972                    ", tag=" + tag + "]");
13973        }
13974
13975        mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
13976    }
13977
13978    public boolean killPids(int[] pids, String pReason, boolean secure) {
13979        if (Binder.getCallingUid() != SYSTEM_UID) {
13980            throw new SecurityException("killPids only available to the system");
13981        }
13982        String reason = (pReason == null) ? "Unknown" : pReason;
13983        // XXX Note: don't acquire main activity lock here, because the window
13984        // manager calls in with its locks held.
13985
13986        boolean killed = false;
13987        synchronized (mPidsSelfLocked) {
13988            int worstType = 0;
13989            for (int i=0; i<pids.length; i++) {
13990                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13991                if (proc != null) {
13992                    int type = proc.setAdj;
13993                    if (type > worstType) {
13994                        worstType = type;
13995                    }
13996                }
13997            }
13998
13999            // If the worst oom_adj is somewhere in the cached proc LRU range,
14000            // then constrain it so we will kill all cached procs.
14001            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
14002                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
14003                worstType = ProcessList.CACHED_APP_MIN_ADJ;
14004            }
14005
14006            // If this is not a secure call, don't let it kill processes that
14007            // are important.
14008            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
14009                worstType = ProcessList.SERVICE_ADJ;
14010            }
14011
14012            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
14013            for (int i=0; i<pids.length; i++) {
14014                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14015                if (proc == null) {
14016                    continue;
14017                }
14018                int adj = proc.setAdj;
14019                if (adj >= worstType && !proc.killedByAm) {
14020                    proc.kill(reason, true);
14021                    killed = true;
14022                }
14023            }
14024        }
14025        return killed;
14026    }
14027
14028    @Override
14029    public void killUid(int appId, int userId, String reason) {
14030        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
14031        synchronized (this) {
14032            final long identity = Binder.clearCallingIdentity();
14033            try {
14034                killPackageProcessesLocked(null, appId, userId,
14035                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
14036                        reason != null ? reason : "kill uid");
14037            } finally {
14038                Binder.restoreCallingIdentity(identity);
14039            }
14040        }
14041    }
14042
14043    @Override
14044    public boolean killProcessesBelowForeground(String reason) {
14045        if (Binder.getCallingUid() != SYSTEM_UID) {
14046            throw new SecurityException("killProcessesBelowForeground() only available to system");
14047        }
14048
14049        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
14050    }
14051
14052    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
14053        if (Binder.getCallingUid() != SYSTEM_UID) {
14054            throw new SecurityException("killProcessesBelowAdj() only available to system");
14055        }
14056
14057        boolean killed = false;
14058        synchronized (mPidsSelfLocked) {
14059            final int size = mPidsSelfLocked.size();
14060            for (int i = 0; i < size; i++) {
14061                final int pid = mPidsSelfLocked.keyAt(i);
14062                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14063                if (proc == null) continue;
14064
14065                final int adj = proc.setAdj;
14066                if (adj > belowAdj && !proc.killedByAm) {
14067                    proc.kill(reason, true);
14068                    killed = true;
14069                }
14070            }
14071        }
14072        return killed;
14073    }
14074
14075    @Override
14076    public void hang(final IBinder who, boolean allowRestart) {
14077        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14078                != PackageManager.PERMISSION_GRANTED) {
14079            throw new SecurityException("Requires permission "
14080                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14081        }
14082
14083        final IBinder.DeathRecipient death = new DeathRecipient() {
14084            @Override
14085            public void binderDied() {
14086                synchronized (this) {
14087                    notifyAll();
14088                }
14089            }
14090        };
14091
14092        try {
14093            who.linkToDeath(death, 0);
14094        } catch (RemoteException e) {
14095            Slog.w(TAG, "hang: given caller IBinder is already dead.");
14096            return;
14097        }
14098
14099        synchronized (this) {
14100            Watchdog.getInstance().setAllowRestart(allowRestart);
14101            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
14102            synchronized (death) {
14103                while (who.isBinderAlive()) {
14104                    try {
14105                        death.wait();
14106                    } catch (InterruptedException e) {
14107                    }
14108                }
14109            }
14110            Watchdog.getInstance().setAllowRestart(true);
14111        }
14112    }
14113
14114    @Override
14115    public void restart() {
14116        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14117                != PackageManager.PERMISSION_GRANTED) {
14118            throw new SecurityException("Requires permission "
14119                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14120        }
14121
14122        Log.i(TAG, "Sending shutdown broadcast...");
14123
14124        BroadcastReceiver br = new BroadcastReceiver() {
14125            @Override public void onReceive(Context context, Intent intent) {
14126                // Now the broadcast is done, finish up the low-level shutdown.
14127                Log.i(TAG, "Shutting down activity manager...");
14128                shutdown(10000);
14129                Log.i(TAG, "Shutdown complete, restarting!");
14130                killProcess(myPid());
14131                System.exit(10);
14132            }
14133        };
14134
14135        // First send the high-level shut down broadcast.
14136        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14137        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14138        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
14139        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
14140        mContext.sendOrderedBroadcastAsUser(intent,
14141                UserHandle.ALL, null, br, mHandler, 0, null, null);
14142        */
14143        br.onReceive(mContext, intent);
14144    }
14145
14146    private long getLowRamTimeSinceIdle(long now) {
14147        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
14148    }
14149
14150    @Override
14151    public void performIdleMaintenance() {
14152        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14153                != PackageManager.PERMISSION_GRANTED) {
14154            throw new SecurityException("Requires permission "
14155                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14156        }
14157
14158        synchronized (this) {
14159            final long now = SystemClock.uptimeMillis();
14160            final long timeSinceLastIdle = now - mLastIdleTime;
14161            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
14162            mLastIdleTime = now;
14163            mLowRamTimeSinceLastIdle = 0;
14164            if (mLowRamStartTime != 0) {
14165                mLowRamStartTime = now;
14166            }
14167
14168            StringBuilder sb = new StringBuilder(128);
14169            sb.append("Idle maintenance over ");
14170            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14171            sb.append(" low RAM for ");
14172            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14173            Slog.i(TAG, sb.toString());
14174
14175            // If at least 1/3 of our time since the last idle period has been spent
14176            // with RAM low, then we want to kill processes.
14177            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14178
14179            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14180                ProcessRecord proc = mLruProcesses.get(i);
14181                if (proc.notCachedSinceIdle) {
14182                    if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
14183                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14184                        if (doKilling && proc.initialIdlePss != 0
14185                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14186                            sb = new StringBuilder(128);
14187                            sb.append("Kill");
14188                            sb.append(proc.processName);
14189                            sb.append(" in idle maint: pss=");
14190                            sb.append(proc.lastPss);
14191                            sb.append(", swapPss=");
14192                            sb.append(proc.lastSwapPss);
14193                            sb.append(", initialPss=");
14194                            sb.append(proc.initialIdlePss);
14195                            sb.append(", period=");
14196                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14197                            sb.append(", lowRamPeriod=");
14198                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14199                            Slog.wtfQuiet(TAG, sb.toString());
14200                            proc.kill("idle maint (pss " + proc.lastPss
14201                                    + " from " + proc.initialIdlePss + ")", true);
14202                        }
14203                    }
14204                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14205                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14206                    proc.notCachedSinceIdle = true;
14207                    proc.initialIdlePss = 0;
14208                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14209                            mTestPssMode, isSleepingLocked(), now);
14210                }
14211            }
14212
14213            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14214            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14215        }
14216    }
14217
14218    @Override
14219    public void sendIdleJobTrigger() {
14220        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14221                != PackageManager.PERMISSION_GRANTED) {
14222            throw new SecurityException("Requires permission "
14223                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14224        }
14225
14226        final long ident = Binder.clearCallingIdentity();
14227        try {
14228            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14229                    .setPackage("android")
14230                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14231            broadcastIntent(null, intent, null, null, 0, null, null, null,
14232                    OP_NONE, null, true, false, UserHandle.USER_ALL);
14233        } finally {
14234            Binder.restoreCallingIdentity(ident);
14235        }
14236    }
14237
14238    private void retrieveSettings() {
14239        final ContentResolver resolver = mContext.getContentResolver();
14240        final boolean freeformWindowManagement =
14241                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14242                        || Settings.Global.getInt(
14243                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14244
14245        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14246        final boolean supportsPictureInPicture = supportsMultiWindow &&
14247                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14248        final boolean supportsSplitScreenMultiWindow =
14249                ActivityManager.supportsSplitScreenMultiWindow(mContext);
14250        final boolean supportsMultiDisplay = mContext.getPackageManager()
14251                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14252        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14253        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14254        final boolean alwaysFinishActivities =
14255                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14256        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14257        final boolean forceResizable = Settings.Global.getInt(
14258                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14259        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14260                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14261        final boolean supportsLeanbackOnly =
14262                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14263
14264        // Transfer any global setting for forcing RTL layout, into a System Property
14265        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14266
14267        final Configuration configuration = new Configuration();
14268        Settings.System.getConfiguration(resolver, configuration);
14269        if (forceRtl) {
14270            // This will take care of setting the correct layout direction flags
14271            configuration.setLayoutDirection(configuration.locale);
14272        }
14273
14274        synchronized (this) {
14275            mDebugApp = mOrigDebugApp = debugApp;
14276            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14277            mAlwaysFinishActivities = alwaysFinishActivities;
14278            mSupportsLeanbackOnly = supportsLeanbackOnly;
14279            mForceResizableActivities = forceResizable;
14280            final boolean multiWindowFormEnabled = freeformWindowManagement
14281                    || supportsSplitScreenMultiWindow
14282                    || supportsPictureInPicture
14283                    || supportsMultiDisplay;
14284            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14285                mSupportsMultiWindow = true;
14286                mSupportsFreeformWindowManagement = freeformWindowManagement;
14287                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14288                mSupportsPictureInPicture = supportsPictureInPicture;
14289                mSupportsMultiDisplay = supportsMultiDisplay;
14290            } else {
14291                mSupportsMultiWindow = false;
14292                mSupportsFreeformWindowManagement = false;
14293                mSupportsSplitScreenMultiWindow = false;
14294                mSupportsPictureInPicture = false;
14295                mSupportsMultiDisplay = false;
14296            }
14297            mWindowManager.setForceResizableTasks(mForceResizableActivities);
14298            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14299            // This happens before any activities are started, so we can change global configuration
14300            // in-place.
14301            updateConfigurationLocked(configuration, null, true);
14302            final Configuration globalConfig = getGlobalConfiguration();
14303            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14304
14305            // Load resources only after the current configuration has been set.
14306            final Resources res = mContext.getResources();
14307            mThumbnailWidth = res.getDimensionPixelSize(
14308                    com.android.internal.R.dimen.thumbnail_width);
14309            mThumbnailHeight = res.getDimensionPixelSize(
14310                    com.android.internal.R.dimen.thumbnail_height);
14311            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14312                    com.android.internal.R.string.config_appsNotReportingCrashes));
14313            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14314                    com.android.internal.R.bool.config_customUserSwitchUi);
14315            mUserController.mMaxRunningUsers = res.getInteger(
14316                    com.android.internal.R.integer.config_multiuserMaxRunningUsers);
14317
14318            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14319                mFullscreenThumbnailScale = (float) res
14320                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14321                    (float) globalConfig.screenWidthDp;
14322            } else {
14323                mFullscreenThumbnailScale = res.getFraction(
14324                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14325            }
14326            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14327        }
14328    }
14329
14330    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14331        traceLog.traceBegin("PhaseActivityManagerReady");
14332        synchronized(this) {
14333            if (mSystemReady) {
14334                // If we're done calling all the receivers, run the next "boot phase" passed in
14335                // by the SystemServer
14336                if (goingCallback != null) {
14337                    goingCallback.run();
14338                }
14339                return;
14340            }
14341
14342            mLocalDeviceIdleController
14343                    = LocalServices.getService(DeviceIdleController.LocalService.class);
14344            mAssistUtils = new AssistUtils(mContext);
14345            mVrController.onSystemReady();
14346            // Make sure we have the current profile info, since it is needed for security checks.
14347            mUserController.onSystemReady();
14348            mRecentTasks.onSystemReadyLocked();
14349            mAppOpsService.systemReady();
14350            mSystemReady = true;
14351        }
14352
14353        try {
14354            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14355                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14356                    .getSerial();
14357        } catch (RemoteException e) {}
14358
14359        ArrayList<ProcessRecord> procsToKill = null;
14360        synchronized(mPidsSelfLocked) {
14361            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14362                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14363                if (!isAllowedWhileBooting(proc.info)){
14364                    if (procsToKill == null) {
14365                        procsToKill = new ArrayList<ProcessRecord>();
14366                    }
14367                    procsToKill.add(proc);
14368                }
14369            }
14370        }
14371
14372        synchronized(this) {
14373            if (procsToKill != null) {
14374                for (int i=procsToKill.size()-1; i>=0; i--) {
14375                    ProcessRecord proc = procsToKill.get(i);
14376                    Slog.i(TAG, "Removing system update proc: " + proc);
14377                    removeProcessLocked(proc, true, false, "system update done");
14378                }
14379            }
14380
14381            // Now that we have cleaned up any update processes, we
14382            // are ready to start launching real processes and know that
14383            // we won't trample on them any more.
14384            mProcessesReady = true;
14385        }
14386
14387        Slog.i(TAG, "System now ready");
14388        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14389            SystemClock.uptimeMillis());
14390
14391        synchronized(this) {
14392            // Make sure we have no pre-ready processes sitting around.
14393
14394            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14395                ResolveInfo ri = mContext.getPackageManager()
14396                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14397                                STOCK_PM_FLAGS);
14398                CharSequence errorMsg = null;
14399                if (ri != null) {
14400                    ActivityInfo ai = ri.activityInfo;
14401                    ApplicationInfo app = ai.applicationInfo;
14402                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14403                        mTopAction = Intent.ACTION_FACTORY_TEST;
14404                        mTopData = null;
14405                        mTopComponent = new ComponentName(app.packageName,
14406                                ai.name);
14407                    } else {
14408                        errorMsg = mContext.getResources().getText(
14409                                com.android.internal.R.string.factorytest_not_system);
14410                    }
14411                } else {
14412                    errorMsg = mContext.getResources().getText(
14413                            com.android.internal.R.string.factorytest_no_action);
14414                }
14415                if (errorMsg != null) {
14416                    mTopAction = null;
14417                    mTopData = null;
14418                    mTopComponent = null;
14419                    Message msg = Message.obtain();
14420                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14421                    msg.getData().putCharSequence("msg", errorMsg);
14422                    mUiHandler.sendMessage(msg);
14423                }
14424            }
14425        }
14426
14427        retrieveSettings();
14428        final int currentUserId = mUserController.getCurrentUserId();
14429        synchronized (this) {
14430            readGrantedUriPermissionsLocked();
14431        }
14432
14433        final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
14434        if (pmi != null) {
14435            pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
14436                    state -> updateForceBackgroundCheck(state.batterySaverEnabled));
14437            updateForceBackgroundCheck(
14438                    pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
14439        } else {
14440            Slog.wtf(TAG, "PowerManagerInternal not found.");
14441        }
14442
14443        if (goingCallback != null) goingCallback.run();
14444        traceLog.traceBegin("ActivityManagerStartApps");
14445        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14446                Integer.toString(currentUserId), currentUserId);
14447        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14448                Integer.toString(currentUserId), currentUserId);
14449        mSystemServiceManager.startUser(currentUserId);
14450
14451        synchronized (this) {
14452            // Only start up encryption-aware persistent apps; once user is
14453            // unlocked we'll come back around and start unaware apps
14454            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14455
14456            // Start up initial activity.
14457            mBooting = true;
14458            // Enable home activity for system user, so that the system can always boot. We don't
14459            // do this when the system user is not setup since the setup wizard should be the one
14460            // to handle home activity in this case.
14461            if (UserManager.isSplitSystemUser() &&
14462                    Settings.Secure.getInt(mContext.getContentResolver(),
14463                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14464                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14465                try {
14466                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14467                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14468                            UserHandle.USER_SYSTEM);
14469                } catch (RemoteException e) {
14470                    throw e.rethrowAsRuntimeException();
14471                }
14472            }
14473            startHomeActivityLocked(currentUserId, "systemReady");
14474
14475            try {
14476                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14477                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14478                            + " data partition or your device will be unstable.");
14479                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14480                }
14481            } catch (RemoteException e) {
14482            }
14483
14484            if (!Build.isBuildConsistent()) {
14485                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14486                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14487            }
14488
14489            long ident = Binder.clearCallingIdentity();
14490            try {
14491                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14492                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14493                        | Intent.FLAG_RECEIVER_FOREGROUND);
14494                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14495                broadcastIntentLocked(null, null, intent,
14496                        null, null, 0, null, null, null, OP_NONE,
14497                        null, false, false, MY_PID, SYSTEM_UID,
14498                        currentUserId);
14499                intent = new Intent(Intent.ACTION_USER_STARTING);
14500                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14501                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14502                broadcastIntentLocked(null, null, intent,
14503                        null, new IIntentReceiver.Stub() {
14504                            @Override
14505                            public void performReceive(Intent intent, int resultCode, String data,
14506                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14507                                    throws RemoteException {
14508                            }
14509                        }, 0, null, null,
14510                        new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
14511                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14512            } catch (Throwable t) {
14513                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14514            } finally {
14515                Binder.restoreCallingIdentity(ident);
14516            }
14517            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14518            mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
14519
14520            BinderInternal.nSetBinderProxyCountEnabled(true);
14521            BinderInternal.setBinderProxyCountCallback(
14522                    new BinderInternal.BinderProxyLimitListener() {
14523                        @Override
14524                        public void onLimitReached(int uid) {
14525                            Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
14526                                    + Process.myUid());
14527                            if (uid == Process.SYSTEM_UID) {
14528                                Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
14529                            } else {
14530                                killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
14531                                        "Too many Binders sent to SYSTEM");
14532                            }
14533                        }
14534                    }, mHandler);
14535
14536            traceLog.traceEnd(); // ActivityManagerStartApps
14537            traceLog.traceEnd(); // PhaseActivityManagerReady
14538        }
14539    }
14540
14541    private void updateForceBackgroundCheck(boolean enabled) {
14542        synchronized (this) {
14543            if (mForceBackgroundCheck != enabled) {
14544                mForceBackgroundCheck = enabled;
14545
14546                if (DEBUG_BACKGROUND_CHECK) {
14547                    Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
14548                }
14549
14550                if (mForceBackgroundCheck) {
14551                    // Stop background services for idle UIDs.
14552                    doStopUidForIdleUidsLocked();
14553                }
14554            }
14555        }
14556    }
14557
14558    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14559        synchronized (this) {
14560            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14561        }
14562    }
14563
14564    void skipCurrentReceiverLocked(ProcessRecord app) {
14565        for (BroadcastQueue queue : mBroadcastQueues) {
14566            queue.skipCurrentReceiverLocked(app);
14567        }
14568    }
14569
14570    /**
14571     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14572     * The application process will exit immediately after this call returns.
14573     * @param app object of the crashing app, null for the system server
14574     * @param crashInfo describing the exception
14575     */
14576    public void handleApplicationCrash(IBinder app,
14577            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14578        ProcessRecord r = findAppProcess(app, "Crash");
14579        final String processName = app == null ? "system_server"
14580                : (r == null ? "unknown" : r.processName);
14581
14582        handleApplicationCrashInner("crash", r, processName, crashInfo);
14583    }
14584
14585    /* Native crash reporting uses this inner version because it needs to be somewhat
14586     * decoupled from the AM-managed cleanup lifecycle
14587     */
14588    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14589            ApplicationErrorReport.CrashInfo crashInfo) {
14590        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14591                UserHandle.getUserId(Binder.getCallingUid()), processName,
14592                r == null ? -1 : r.info.flags,
14593                crashInfo.exceptionClassName,
14594                crashInfo.exceptionMessage,
14595                crashInfo.throwFileName,
14596                crashInfo.throwLineNumber);
14597
14598        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14599
14600        mAppErrors.crashApplication(r, crashInfo);
14601    }
14602
14603    public void handleApplicationStrictModeViolation(
14604            IBinder app,
14605            int violationMask,
14606            StrictMode.ViolationInfo info) {
14607        // We're okay if the ProcessRecord is missing; it probably means that
14608        // we're reporting a violation from the system process itself.
14609        final ProcessRecord r = findAppProcess(app, "StrictMode");
14610
14611        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14612            Integer stackFingerprint = info.hashCode();
14613            boolean logIt = true;
14614            synchronized (mAlreadyLoggedViolatedStacks) {
14615                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14616                    logIt = false;
14617                    // TODO: sub-sample into EventLog for these, with
14618                    // the info.durationMillis?  Then we'd get
14619                    // the relative pain numbers, without logging all
14620                    // the stack traces repeatedly.  We'd want to do
14621                    // likewise in the client code, which also does
14622                    // dup suppression, before the Binder call.
14623                } else {
14624                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14625                        mAlreadyLoggedViolatedStacks.clear();
14626                    }
14627                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14628                }
14629            }
14630            if (logIt) {
14631                logStrictModeViolationToDropBox(r, info);
14632            }
14633        }
14634
14635        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14636            AppErrorResult result = new AppErrorResult();
14637            synchronized (this) {
14638                final long origId = Binder.clearCallingIdentity();
14639
14640                Message msg = Message.obtain();
14641                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14642                HashMap<String, Object> data = new HashMap<String, Object>();
14643                data.put("result", result);
14644                data.put("app", r);
14645                data.put("violationMask", violationMask);
14646                data.put("info", info);
14647                msg.obj = data;
14648                mUiHandler.sendMessage(msg);
14649
14650                Binder.restoreCallingIdentity(origId);
14651            }
14652            int res = result.get();
14653            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14654        }
14655    }
14656
14657    // Depending on the policy in effect, there could be a bunch of
14658    // these in quick succession so we try to batch these together to
14659    // minimize disk writes, number of dropbox entries, and maximize
14660    // compression, by having more fewer, larger records.
14661    private void logStrictModeViolationToDropBox(
14662            ProcessRecord process,
14663            StrictMode.ViolationInfo info) {
14664        if (info == null) {
14665            return;
14666        }
14667        final boolean isSystemApp = process == null ||
14668                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14669                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14670        final String processName = process == null ? "unknown" : process.processName;
14671        final DropBoxManager dbox = (DropBoxManager)
14672                mContext.getSystemService(Context.DROPBOX_SERVICE);
14673
14674        // Exit early if the dropbox isn't configured to accept this report type.
14675        final String dropboxTag = processClass(process) + "_strictmode";
14676        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14677
14678        final StringBuilder sb = new StringBuilder(1024);
14679        synchronized (sb) {
14680            appendDropBoxProcessHeaders(process, processName, sb);
14681            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14682            sb.append("System-App: ").append(isSystemApp).append("\n");
14683            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14684            if (info.violationNumThisLoop != 0) {
14685                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14686            }
14687            if (info.numAnimationsRunning != 0) {
14688                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14689            }
14690            if (info.broadcastIntentAction != null) {
14691                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14692            }
14693            if (info.durationMillis != -1) {
14694                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14695            }
14696            if (info.numInstances != -1) {
14697                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14698            }
14699            if (info.tags != null) {
14700                for (String tag : info.tags) {
14701                    sb.append("Span-Tag: ").append(tag).append("\n");
14702                }
14703            }
14704            sb.append("\n");
14705            sb.append(info.getStackTrace());
14706            sb.append("\n");
14707            if (info.getViolationDetails() != null) {
14708                sb.append(info.getViolationDetails());
14709                sb.append("\n");
14710            }
14711        }
14712
14713        final String res = sb.toString();
14714        IoThread.getHandler().post(() -> {
14715            dbox.addText(dropboxTag, res);
14716        });
14717    }
14718
14719    /**
14720     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14721     * @param app object of the crashing app, null for the system server
14722     * @param tag reported by the caller
14723     * @param system whether this wtf is coming from the system
14724     * @param crashInfo describing the context of the error
14725     * @return true if the process should exit immediately (WTF is fatal)
14726     */
14727    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14728            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14729        final int callingUid = Binder.getCallingUid();
14730        final int callingPid = Binder.getCallingPid();
14731
14732        if (system) {
14733            // If this is coming from the system, we could very well have low-level
14734            // system locks held, so we want to do this all asynchronously.  And we
14735            // never want this to become fatal, so there is that too.
14736            mHandler.post(new Runnable() {
14737                @Override public void run() {
14738                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14739                }
14740            });
14741            return false;
14742        }
14743
14744        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14745                crashInfo);
14746
14747        final boolean isFatal = Build.IS_ENG || Settings.Global
14748                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14749        final boolean isSystem = (r == null) || r.persistent;
14750
14751        if (isFatal && !isSystem) {
14752            mAppErrors.crashApplication(r, crashInfo);
14753            return true;
14754        } else {
14755            return false;
14756        }
14757    }
14758
14759    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14760            final ApplicationErrorReport.CrashInfo crashInfo) {
14761        final ProcessRecord r = findAppProcess(app, "WTF");
14762        final String processName = app == null ? "system_server"
14763                : (r == null ? "unknown" : r.processName);
14764
14765        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14766                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14767
14768        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14769
14770        return r;
14771    }
14772
14773    /**
14774     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14775     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14776     */
14777    private ProcessRecord findAppProcess(IBinder app, String reason) {
14778        if (app == null) {
14779            return null;
14780        }
14781
14782        synchronized (this) {
14783            final int NP = mProcessNames.getMap().size();
14784            for (int ip=0; ip<NP; ip++) {
14785                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14786                final int NA = apps.size();
14787                for (int ia=0; ia<NA; ia++) {
14788                    ProcessRecord p = apps.valueAt(ia);
14789                    if (p.thread != null && p.thread.asBinder() == app) {
14790                        return p;
14791                    }
14792                }
14793            }
14794
14795            Slog.w(TAG, "Can't find mystery application for " + reason
14796                    + " from pid=" + Binder.getCallingPid()
14797                    + " uid=" + Binder.getCallingUid() + ": " + app);
14798            return null;
14799        }
14800    }
14801
14802    /**
14803     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14804     * to append various headers to the dropbox log text.
14805     */
14806    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14807            StringBuilder sb) {
14808        // Watchdog thread ends up invoking this function (with
14809        // a null ProcessRecord) to add the stack file to dropbox.
14810        // Do not acquire a lock on this (am) in such cases, as it
14811        // could cause a potential deadlock, if and when watchdog
14812        // is invoked due to unavailability of lock on am and it
14813        // would prevent watchdog from killing system_server.
14814        if (process == null) {
14815            sb.append("Process: ").append(processName).append("\n");
14816            return;
14817        }
14818        // Note: ProcessRecord 'process' is guarded by the service
14819        // instance.  (notably process.pkgList, which could otherwise change
14820        // concurrently during execution of this method)
14821        synchronized (this) {
14822            sb.append("Process: ").append(processName).append("\n");
14823            sb.append("PID: ").append(process.pid).append("\n");
14824            int flags = process.info.flags;
14825            IPackageManager pm = AppGlobals.getPackageManager();
14826            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14827            for (int ip=0; ip<process.pkgList.size(); ip++) {
14828                String pkg = process.pkgList.keyAt(ip);
14829                sb.append("Package: ").append(pkg);
14830                try {
14831                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14832                    if (pi != null) {
14833                        sb.append(" v").append(pi.getLongVersionCode());
14834                        if (pi.versionName != null) {
14835                            sb.append(" (").append(pi.versionName).append(")");
14836                        }
14837                    }
14838                } catch (RemoteException e) {
14839                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14840                }
14841                sb.append("\n");
14842            }
14843            if (process.info.isInstantApp()) {
14844                sb.append("Instant-App: true\n");
14845            }
14846        }
14847    }
14848
14849    private static String processClass(ProcessRecord process) {
14850        if (process == null || process.pid == MY_PID) {
14851            return "system_server";
14852        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14853            return "system_app";
14854        } else {
14855            return "data_app";
14856        }
14857    }
14858
14859    private volatile long mWtfClusterStart;
14860    private volatile int mWtfClusterCount;
14861
14862    /**
14863     * Write a description of an error (crash, WTF, ANR) to the drop box.
14864     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14865     * @param process which caused the error, null means the system server
14866     * @param activity which triggered the error, null if unknown
14867     * @param parent activity related to the error, null if unknown
14868     * @param subject line related to the error, null if absent
14869     * @param report in long form describing the error, null if absent
14870     * @param dataFile text file to include in the report, null if none
14871     * @param crashInfo giving an application stack trace, null if absent
14872     */
14873    public void addErrorToDropBox(String eventType,
14874            ProcessRecord process, String processName, ActivityRecord activity,
14875            ActivityRecord parent, String subject,
14876            final String report, final File dataFile,
14877            final ApplicationErrorReport.CrashInfo crashInfo) {
14878        // NOTE -- this must never acquire the ActivityManagerService lock,
14879        // otherwise the watchdog may be prevented from resetting the system.
14880
14881        // Bail early if not published yet
14882        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14883        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14884
14885        // Exit early if the dropbox isn't configured to accept this report type.
14886        final String dropboxTag = processClass(process) + "_" + eventType;
14887        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14888
14889        // Log to StatsLog before the rate-limiting.
14890        // The logging below is adapated from appendDropboxProcessHeaders.
14891        StatsLog.write(StatsLog.DROPBOX_ERROR_CHANGED,
14892                process != null ? process.uid : -1,
14893                dropboxTag,
14894                processName,
14895                process != null ? process.pid : -1,
14896                (process != null && process.info != null) ?
14897                        (process.info.isInstantApp() ? 1 : 0) : -1,
14898                activity != null ? activity.shortComponentName : null,
14899                activity != null ? activity.packageName : null,
14900                process != null ? (process.isInterestingToUserLocked() ? 1 : 0) : -1);
14901
14902        // Rate-limit how often we're willing to do the heavy lifting below to
14903        // collect and record logs; currently 5 logs per 10 second period.
14904        final long now = SystemClock.elapsedRealtime();
14905        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14906            mWtfClusterStart = now;
14907            mWtfClusterCount = 1;
14908        } else {
14909            if (mWtfClusterCount++ >= 5) return;
14910        }
14911
14912        final StringBuilder sb = new StringBuilder(1024);
14913        appendDropBoxProcessHeaders(process, processName, sb);
14914        if (process != null) {
14915            sb.append("Foreground: ")
14916                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14917                    .append("\n");
14918        }
14919        if (activity != null) {
14920            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14921        }
14922        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14923            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14924        }
14925        if (parent != null && parent != activity) {
14926            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14927        }
14928        if (subject != null) {
14929            sb.append("Subject: ").append(subject).append("\n");
14930        }
14931        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14932        if (Debug.isDebuggerConnected()) {
14933            sb.append("Debugger: Connected\n");
14934        }
14935        sb.append("\n");
14936
14937        // Do the rest in a worker thread to avoid blocking the caller on I/O
14938        // (After this point, we shouldn't access AMS internal data structures.)
14939        Thread worker = new Thread("Error dump: " + dropboxTag) {
14940            @Override
14941            public void run() {
14942                if (report != null) {
14943                    sb.append(report);
14944                }
14945
14946                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14947                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14948                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14949                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14950
14951                if (dataFile != null && maxDataFileSize > 0) {
14952                    try {
14953                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14954                                    "\n\n[[TRUNCATED]]"));
14955                    } catch (IOException e) {
14956                        Slog.e(TAG, "Error reading " + dataFile, e);
14957                    }
14958                }
14959                if (crashInfo != null && crashInfo.stackTrace != null) {
14960                    sb.append(crashInfo.stackTrace);
14961                }
14962
14963                if (lines > 0) {
14964                    sb.append("\n");
14965
14966                    // Merge several logcat streams, and take the last N lines
14967                    InputStreamReader input = null;
14968                    try {
14969                        java.lang.Process logcat = new ProcessBuilder(
14970                                "/system/bin/timeout", "-k", "15s", "10s",
14971                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14972                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14973                                        .redirectErrorStream(true).start();
14974
14975                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14976                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14977                        input = new InputStreamReader(logcat.getInputStream());
14978
14979                        int num;
14980                        char[] buf = new char[8192];
14981                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14982                    } catch (IOException e) {
14983                        Slog.e(TAG, "Error running logcat", e);
14984                    } finally {
14985                        if (input != null) try { input.close(); } catch (IOException e) {}
14986                    }
14987                }
14988
14989                dbox.addText(dropboxTag, sb.toString());
14990            }
14991        };
14992
14993        if (process == null) {
14994            // If process is null, we are being called from some internal code
14995            // and may be about to die -- run this synchronously.
14996            final int oldMask = StrictMode.allowThreadDiskWritesMask();
14997            try {
14998                worker.run();
14999            } finally {
15000                StrictMode.setThreadPolicyMask(oldMask);
15001            }
15002        } else {
15003            worker.start();
15004        }
15005    }
15006
15007    @Override
15008    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
15009        enforceNotIsolatedCaller("getProcessesInErrorState");
15010        // assume our apps are happy - lazy create the list
15011        List<ActivityManager.ProcessErrorStateInfo> errList = null;
15012
15013        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15014                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
15015        int userId = UserHandle.getUserId(Binder.getCallingUid());
15016
15017        synchronized (this) {
15018
15019            // iterate across all processes
15020            for (int i=mLruProcesses.size()-1; i>=0; i--) {
15021                ProcessRecord app = mLruProcesses.get(i);
15022                if (!allUsers && app.userId != userId) {
15023                    continue;
15024                }
15025                if ((app.thread != null) && (app.crashing || app.notResponding)) {
15026                    // This one's in trouble, so we'll generate a report for it
15027                    // crashes are higher priority (in case there's a crash *and* an anr)
15028                    ActivityManager.ProcessErrorStateInfo report = null;
15029                    if (app.crashing) {
15030                        report = app.crashingReport;
15031                    } else if (app.notResponding) {
15032                        report = app.notRespondingReport;
15033                    }
15034
15035                    if (report != null) {
15036                        if (errList == null) {
15037                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
15038                        }
15039                        errList.add(report);
15040                    } else {
15041                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
15042                                " crashing = " + app.crashing +
15043                                " notResponding = " + app.notResponding);
15044                    }
15045                }
15046            }
15047        }
15048
15049        return errList;
15050    }
15051
15052    static int procStateToImportance(int procState, int memAdj,
15053            ActivityManager.RunningAppProcessInfo currApp,
15054            int clientTargetSdk) {
15055        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
15056                procState, clientTargetSdk);
15057        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
15058            currApp.lru = memAdj;
15059        } else {
15060            currApp.lru = 0;
15061        }
15062        return imp;
15063    }
15064
15065    private void fillInProcMemInfo(ProcessRecord app,
15066            ActivityManager.RunningAppProcessInfo outInfo,
15067            int clientTargetSdk) {
15068        outInfo.pid = app.pid;
15069        outInfo.uid = app.info.uid;
15070        if (mHeavyWeightProcess == app) {
15071            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
15072        }
15073        if (app.persistent) {
15074            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
15075        }
15076        if (app.activities.size() > 0) {
15077            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
15078        }
15079        outInfo.lastTrimLevel = app.trimMemoryLevel;
15080        int adj = app.curAdj;
15081        int procState = app.curProcState;
15082        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
15083        outInfo.importanceReasonCode = app.adjTypeCode;
15084        outInfo.processState = app.curProcState;
15085    }
15086
15087    @Override
15088    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
15089        enforceNotIsolatedCaller("getRunningAppProcesses");
15090
15091        final int callingUid = Binder.getCallingUid();
15092        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15093
15094        // Lazy instantiation of list
15095        List<ActivityManager.RunningAppProcessInfo> runList = null;
15096        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15097                callingUid) == PackageManager.PERMISSION_GRANTED;
15098        final int userId = UserHandle.getUserId(callingUid);
15099        final boolean allUids = isGetTasksAllowed(
15100                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
15101
15102        synchronized (this) {
15103            // Iterate across all processes
15104            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15105                ProcessRecord app = mLruProcesses.get(i);
15106                if ((!allUsers && app.userId != userId)
15107                        || (!allUids && app.uid != callingUid)) {
15108                    continue;
15109                }
15110                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
15111                    // Generate process state info for running application
15112                    ActivityManager.RunningAppProcessInfo currApp =
15113                        new ActivityManager.RunningAppProcessInfo(app.processName,
15114                                app.pid, app.getPackageList());
15115                    fillInProcMemInfo(app, currApp, clientTargetSdk);
15116                    if (app.adjSource instanceof ProcessRecord) {
15117                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
15118                        currApp.importanceReasonImportance =
15119                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
15120                                        app.adjSourceProcState);
15121                    } else if (app.adjSource instanceof ActivityRecord) {
15122                        ActivityRecord r = (ActivityRecord)app.adjSource;
15123                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
15124                    }
15125                    if (app.adjTarget instanceof ComponentName) {
15126                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
15127                    }
15128                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
15129                    //        + " lru=" + currApp.lru);
15130                    if (runList == null) {
15131                        runList = new ArrayList<>();
15132                    }
15133                    runList.add(currApp);
15134                }
15135            }
15136        }
15137        return runList;
15138    }
15139
15140    @Override
15141    public List<ApplicationInfo> getRunningExternalApplications() {
15142        enforceNotIsolatedCaller("getRunningExternalApplications");
15143        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
15144        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
15145        if (runningApps != null && runningApps.size() > 0) {
15146            Set<String> extList = new HashSet<String>();
15147            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
15148                if (app.pkgList != null) {
15149                    for (String pkg : app.pkgList) {
15150                        extList.add(pkg);
15151                    }
15152                }
15153            }
15154            IPackageManager pm = AppGlobals.getPackageManager();
15155            for (String pkg : extList) {
15156                try {
15157                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
15158                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
15159                        retList.add(info);
15160                    }
15161                } catch (RemoteException e) {
15162                }
15163            }
15164        }
15165        return retList;
15166    }
15167
15168    @Override
15169    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15170        enforceNotIsolatedCaller("getMyMemoryState");
15171
15172        final int callingUid = Binder.getCallingUid();
15173        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15174
15175        synchronized (this) {
15176            ProcessRecord proc;
15177            synchronized (mPidsSelfLocked) {
15178                proc = mPidsSelfLocked.get(Binder.getCallingPid());
15179            }
15180            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15181        }
15182    }
15183
15184    @Override
15185    public int getMemoryTrimLevel() {
15186        enforceNotIsolatedCaller("getMyMemoryState");
15187        synchronized (this) {
15188            return mLastMemoryLevel;
15189        }
15190    }
15191
15192    @Override
15193    public void onShellCommand(FileDescriptor in, FileDescriptor out,
15194            FileDescriptor err, String[] args, ShellCallback callback,
15195            ResultReceiver resultReceiver) {
15196        (new ActivityManagerShellCommand(this, false)).exec(
15197                this, in, out, err, args, callback, resultReceiver);
15198    }
15199
15200    SleepToken acquireSleepToken(String tag, int displayId) {
15201        synchronized (this) {
15202            final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15203            updateSleepIfNeededLocked();
15204            return token;
15205        }
15206    }
15207
15208    @Override
15209    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15210        PriorityDump.dump(mPriorityDumper, fd, pw, args);
15211    }
15212
15213    /**
15214     * Wrapper function to print out debug data filtered by specified arguments.
15215    */
15216    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
15217        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15218
15219        boolean dumpAll = false;
15220        boolean dumpClient = false;
15221        boolean dumpCheckin = false;
15222        boolean dumpCheckinFormat = false;
15223        boolean dumpVisibleStacksOnly = false;
15224        boolean dumpFocusedStackOnly = false;
15225        String dumpPackage = null;
15226        int dumpAppId = -1;
15227
15228        int opti = 0;
15229        while (opti < args.length) {
15230            String opt = args[opti];
15231            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15232                break;
15233            }
15234            opti++;
15235            if ("-a".equals(opt)) {
15236                dumpAll = true;
15237            } else if ("-c".equals(opt)) {
15238                dumpClient = true;
15239            } else if ("-v".equals(opt)) {
15240                dumpVisibleStacksOnly = true;
15241            } else if ("-f".equals(opt)) {
15242                dumpFocusedStackOnly = true;
15243            } else if ("-p".equals(opt)) {
15244                if (opti < args.length) {
15245                    dumpPackage = args[opti];
15246                    opti++;
15247                } else {
15248                    pw.println("Error: -p option requires package argument");
15249                    return;
15250                }
15251                dumpClient = true;
15252            } else if ("--checkin".equals(opt)) {
15253                dumpCheckin = dumpCheckinFormat = true;
15254            } else if ("-C".equals(opt)) {
15255                dumpCheckinFormat = true;
15256            } else if ("-h".equals(opt)) {
15257                ActivityManagerShellCommand.dumpHelp(pw, true);
15258                return;
15259            } else {
15260                pw.println("Unknown argument: " + opt + "; use -h for help");
15261            }
15262        }
15263
15264        long origId = Binder.clearCallingIdentity();
15265
15266        if (useProto) {
15267            final ProtoOutputStream proto = new ProtoOutputStream(fd);
15268            String cmd = opti < args.length ? args[opti] : "";
15269            opti++;
15270
15271            if ("activities".equals(cmd) || "a".equals(cmd)) {
15272                // output proto is ActivityStackSupervisorProto
15273                synchronized (this) {
15274                    writeActivitiesToProtoLocked(proto);
15275                }
15276            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15277                // output proto is BroadcastProto
15278                synchronized (this) {
15279                    writeBroadcastsToProtoLocked(proto);
15280                }
15281            } else if ("provider".equals(cmd)) {
15282                String[] newArgs;
15283                String name;
15284                if (opti >= args.length) {
15285                    name = null;
15286                    newArgs = EMPTY_STRING_ARRAY;
15287                } else {
15288                    name = args[opti];
15289                    opti++;
15290                    newArgs = new String[args.length - opti];
15291                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15292                            args.length - opti);
15293                }
15294                if (!dumpProviderProto(fd, pw, name, newArgs)) {
15295                    pw.println("No providers match: " + name);
15296                    pw.println("Use -h for help.");
15297                }
15298            } else if ("service".equals(cmd)) {
15299                mServices.writeToProto(proto);
15300            } else {
15301                // default option, dump everything, output is ActivityManagerServiceProto
15302                synchronized (this) {
15303                    long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
15304                    writeActivitiesToProtoLocked(proto);
15305                    proto.end(activityToken);
15306
15307                    long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
15308                    writeBroadcastsToProtoLocked(proto);
15309                    proto.end(broadcastToken);
15310
15311                    long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
15312                    mServices.writeToProto(proto);
15313                    proto.end(serviceToken);
15314                }
15315            }
15316            proto.flush();
15317            Binder.restoreCallingIdentity(origId);
15318            return;
15319        }
15320
15321        if (dumpPackage != null) {
15322            try {
15323                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15324                        dumpPackage, 0);
15325                dumpAppId = UserHandle.getAppId(info.uid);
15326            } catch (NameNotFoundException e) {
15327                e.printStackTrace();
15328            }
15329        }
15330
15331        boolean more = false;
15332        // Is the caller requesting to dump a particular piece of data?
15333        if (opti < args.length) {
15334            String cmd = args[opti];
15335            opti++;
15336            if ("activities".equals(cmd) || "a".equals(cmd)) {
15337                synchronized (this) {
15338                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15339                }
15340            } else if ("lastanr".equals(cmd)) {
15341                synchronized (this) {
15342                    dumpLastANRLocked(pw);
15343                }
15344            } else if ("starter".equals(cmd)) {
15345                synchronized (this) {
15346                    dumpActivityStarterLocked(pw, dumpPackage);
15347                }
15348            } else if ("containers".equals(cmd)) {
15349                synchronized (this) {
15350                    dumpActivityContainersLocked(pw);
15351                }
15352            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15353                synchronized (this) {
15354                    if (mRecentTasks != null) {
15355                        mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
15356                    }
15357                }
15358            } else if ("binder-proxies".equals(cmd)) {
15359                if (opti >= args.length) {
15360                    dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
15361                            "Counts of Binder Proxies held by SYSTEM");
15362                } else {
15363                    String uid = args[opti];
15364                    opti++;
15365                    // Ensure Binder Proxy Count is as up to date as possible
15366                    System.gc();
15367                    System.runFinalization();
15368                    System.gc();
15369                    pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
15370                }
15371            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15372                String[] newArgs;
15373                String name;
15374                if (opti >= args.length) {
15375                    name = null;
15376                    newArgs = EMPTY_STRING_ARRAY;
15377                } else {
15378                    dumpPackage = args[opti];
15379                    opti++;
15380                    newArgs = new String[args.length - opti];
15381                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15382                            args.length - opti);
15383                }
15384                synchronized (this) {
15385                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15386                }
15387            } else if ("broadcast-stats".equals(cmd)) {
15388                String[] newArgs;
15389                String name;
15390                if (opti >= args.length) {
15391                    name = null;
15392                    newArgs = EMPTY_STRING_ARRAY;
15393                } else {
15394                    dumpPackage = args[opti];
15395                    opti++;
15396                    newArgs = new String[args.length - opti];
15397                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15398                            args.length - opti);
15399                }
15400                synchronized (this) {
15401                    if (dumpCheckinFormat) {
15402                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15403                                dumpPackage);
15404                    } else {
15405                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15406                    }
15407                }
15408            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15409                String[] newArgs;
15410                String name;
15411                if (opti >= args.length) {
15412                    name = null;
15413                    newArgs = EMPTY_STRING_ARRAY;
15414                } else {
15415                    dumpPackage = args[opti];
15416                    opti++;
15417                    newArgs = new String[args.length - opti];
15418                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15419                            args.length - opti);
15420                }
15421                synchronized (this) {
15422                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15423                }
15424            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15425                String[] newArgs;
15426                String name;
15427                if (opti >= args.length) {
15428                    name = null;
15429                    newArgs = EMPTY_STRING_ARRAY;
15430                } else {
15431                    dumpPackage = args[opti];
15432                    opti++;
15433                    newArgs = new String[args.length - opti];
15434                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15435                            args.length - opti);
15436                }
15437                synchronized (this) {
15438                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
15439                }
15440            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15441                synchronized (this) {
15442                    dumpOomLocked(fd, pw, args, opti, true);
15443                }
15444            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15445                synchronized (this) {
15446                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
15447                }
15448            } else if ("provider".equals(cmd)) {
15449                String[] newArgs;
15450                String name;
15451                if (opti >= args.length) {
15452                    name = null;
15453                    newArgs = EMPTY_STRING_ARRAY;
15454                } else {
15455                    name = args[opti];
15456                    opti++;
15457                    newArgs = new String[args.length - opti];
15458                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15459                }
15460                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15461                    pw.println("No providers match: " + name);
15462                    pw.println("Use -h for help.");
15463                }
15464            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15465                synchronized (this) {
15466                    dumpProvidersLocked(fd, pw, args, opti, true, null);
15467                }
15468            } else if ("service".equals(cmd)) {
15469                String[] newArgs;
15470                String name;
15471                if (opti >= args.length) {
15472                    name = null;
15473                    newArgs = EMPTY_STRING_ARRAY;
15474                } else {
15475                    name = args[opti];
15476                    opti++;
15477                    newArgs = new String[args.length - opti];
15478                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15479                            args.length - opti);
15480                }
15481                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15482                    pw.println("No services match: " + name);
15483                    pw.println("Use -h for help.");
15484                }
15485            } else if ("package".equals(cmd)) {
15486                String[] newArgs;
15487                if (opti >= args.length) {
15488                    pw.println("package: no package name specified");
15489                    pw.println("Use -h for help.");
15490                } else {
15491                    dumpPackage = args[opti];
15492                    opti++;
15493                    newArgs = new String[args.length - opti];
15494                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15495                            args.length - opti);
15496                    args = newArgs;
15497                    opti = 0;
15498                    more = true;
15499                }
15500            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15501                synchronized (this) {
15502                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15503                }
15504            } else if ("settings".equals(cmd)) {
15505                synchronized (this) {
15506                    mConstants.dump(pw);
15507                }
15508            } else if ("services".equals(cmd) || "s".equals(cmd)) {
15509                if (dumpClient) {
15510                    ActiveServices.ServiceDumper dumper;
15511                    synchronized (this) {
15512                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15513                                dumpPackage);
15514                    }
15515                    dumper.dumpWithClient();
15516                } else {
15517                    synchronized (this) {
15518                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15519                                dumpPackage).dumpLocked();
15520                    }
15521                }
15522            } else if ("locks".equals(cmd)) {
15523                LockGuard.dump(fd, pw, args);
15524            } else {
15525                // Dumping a single activity?
15526                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15527                        dumpFocusedStackOnly)) {
15528                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15529                    int res = shell.exec(this, null, fd, null, args, null,
15530                            new ResultReceiver(null));
15531                    if (res < 0) {
15532                        pw.println("Bad activity command, or no activities match: " + cmd);
15533                        pw.println("Use -h for help.");
15534                    }
15535                }
15536            }
15537            if (!more) {
15538                Binder.restoreCallingIdentity(origId);
15539                return;
15540            }
15541        }
15542
15543        // No piece of data specified, dump everything.
15544        if (dumpCheckinFormat) {
15545            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15546        } else if (dumpClient) {
15547            ActiveServices.ServiceDumper sdumper;
15548            synchronized (this) {
15549                mConstants.dump(pw);
15550                pw.println();
15551                if (dumpAll) {
15552                    pw.println("-------------------------------------------------------------------------------");
15553                }
15554                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15555                pw.println();
15556                if (dumpAll) {
15557                    pw.println("-------------------------------------------------------------------------------");
15558                }
15559                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15560                pw.println();
15561                if (dumpAll) {
15562                    pw.println("-------------------------------------------------------------------------------");
15563                }
15564                if (dumpAll || dumpPackage != null) {
15565                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15566                    pw.println();
15567                    if (dumpAll) {
15568                        pw.println("-------------------------------------------------------------------------------");
15569                    }
15570                }
15571                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15572                pw.println();
15573                if (dumpAll) {
15574                    pw.println("-------------------------------------------------------------------------------");
15575                }
15576                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15577                pw.println();
15578                if (dumpAll) {
15579                    pw.println("-------------------------------------------------------------------------------");
15580                }
15581                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15582                        dumpPackage);
15583            }
15584            sdumper.dumpWithClient();
15585            pw.println();
15586            synchronized (this) {
15587                if (dumpAll) {
15588                    pw.println("-------------------------------------------------------------------------------");
15589                }
15590                if (mRecentTasks != null) {
15591                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
15592                }
15593                pw.println();
15594                if (dumpAll) {
15595                    pw.println("-------------------------------------------------------------------------------");
15596                }
15597                dumpLastANRLocked(pw);
15598                pw.println();
15599                if (dumpAll) {
15600                    pw.println("-------------------------------------------------------------------------------");
15601                }
15602                dumpActivityStarterLocked(pw, dumpPackage);
15603                pw.println();
15604                if (dumpAll) {
15605                    pw.println("-------------------------------------------------------------------------------");
15606                }
15607                dumpActivityContainersLocked(pw);
15608                pw.println();
15609                if (dumpAll) {
15610                    pw.println("-------------------------------------------------------------------------------");
15611                }
15612                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15613                if (mAssociations.size() > 0) {
15614                    pw.println();
15615                    if (dumpAll) {
15616                        pw.println("-------------------------------------------------------------------------------");
15617                    }
15618                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15619                }
15620                pw.println();
15621                if (dumpAll) {
15622                    pw.println("-------------------------------------------------------------------------------");
15623                }
15624                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
15625            }
15626
15627        } else {
15628            synchronized (this) {
15629                mConstants.dump(pw);
15630                pw.println();
15631                if (dumpAll) {
15632                    pw.println("-------------------------------------------------------------------------------");
15633                }
15634                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15635                pw.println();
15636                if (dumpAll) {
15637                    pw.println("-------------------------------------------------------------------------------");
15638                }
15639                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15640                pw.println();
15641                if (dumpAll) {
15642                    pw.println("-------------------------------------------------------------------------------");
15643                }
15644                if (dumpAll || dumpPackage != null) {
15645                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15646                    pw.println();
15647                    if (dumpAll) {
15648                        pw.println("-------------------------------------------------------------------------------");
15649                    }
15650                }
15651                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15652                pw.println();
15653                if (dumpAll) {
15654                    pw.println("-------------------------------------------------------------------------------");
15655                }
15656                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15657                pw.println();
15658                if (dumpAll) {
15659                    pw.println("-------------------------------------------------------------------------------");
15660                }
15661                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15662                        .dumpLocked();
15663                pw.println();
15664                if (dumpAll) {
15665                    pw.println("-------------------------------------------------------------------------------");
15666                }
15667                if (mRecentTasks != null) {
15668                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
15669                }
15670                pw.println();
15671                if (dumpAll) {
15672                    pw.println("-------------------------------------------------------------------------------");
15673                }
15674                dumpLastANRLocked(pw);
15675                pw.println();
15676                if (dumpAll) {
15677                    pw.println("-------------------------------------------------------------------------------");
15678                }
15679                dumpActivityStarterLocked(pw, dumpPackage);
15680                pw.println();
15681                if (dumpAll) {
15682                    pw.println("-------------------------------------------------------------------------------");
15683                }
15684                dumpActivityContainersLocked(pw);
15685                pw.println();
15686                if (dumpAll) {
15687                    pw.println("-------------------------------------------------------------------------------");
15688                }
15689                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15690                if (mAssociations.size() > 0) {
15691                    pw.println();
15692                    if (dumpAll) {
15693                        pw.println("-------------------------------------------------------------------------------");
15694                    }
15695                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15696                }
15697                pw.println();
15698                if (dumpAll) {
15699                    pw.println("-------------------------------------------------------------------------------");
15700                }
15701                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
15702            }
15703        }
15704        Binder.restoreCallingIdentity(origId);
15705    }
15706
15707    private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
15708        // The output proto of "activity --proto activities" is ActivityStackSupervisorProto
15709        mStackSupervisor.writeToProto(proto);
15710    }
15711
15712    private void dumpLastANRLocked(PrintWriter pw) {
15713        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15714        if (mLastANRState == null) {
15715            pw.println("  <no ANR has occurred since boot>");
15716        } else {
15717            pw.println(mLastANRState);
15718        }
15719    }
15720
15721    private void dumpActivityContainersLocked(PrintWriter pw) {
15722        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
15723        mStackSupervisor.dumpChildrenNames(pw, " ");
15724        pw.println(" ");
15725    }
15726
15727    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15728        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15729        mActivityStartController.dump(pw, "", dumpPackage);
15730    }
15731
15732    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15733            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15734        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15735                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15736    }
15737
15738    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15739            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15740        pw.println(header);
15741
15742        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15743                dumpPackage);
15744        boolean needSep = printedAnything;
15745
15746        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15747                mStackSupervisor.getResumedActivityLocked(),
15748                dumpPackage, needSep, "  ResumedActivity: ");
15749        if (printed) {
15750            printedAnything = true;
15751            needSep = false;
15752        }
15753
15754        if (dumpPackage == null) {
15755            if (needSep) {
15756                pw.println();
15757            }
15758            printedAnything = true;
15759            mStackSupervisor.dump(pw, "  ");
15760        }
15761
15762        if (!printedAnything) {
15763            pw.println("  (nothing)");
15764        }
15765    }
15766
15767    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15768            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15769        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15770
15771        int dumpUid = 0;
15772        if (dumpPackage != null) {
15773            IPackageManager pm = AppGlobals.getPackageManager();
15774            try {
15775                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15776            } catch (RemoteException e) {
15777            }
15778        }
15779
15780        boolean printedAnything = false;
15781
15782        final long now = SystemClock.uptimeMillis();
15783
15784        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15785            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15786                    = mAssociations.valueAt(i1);
15787            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15788                SparseArray<ArrayMap<String, Association>> sourceUids
15789                        = targetComponents.valueAt(i2);
15790                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15791                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15792                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15793                        Association ass = sourceProcesses.valueAt(i4);
15794                        if (dumpPackage != null) {
15795                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15796                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15797                                continue;
15798                            }
15799                        }
15800                        printedAnything = true;
15801                        pw.print("  ");
15802                        pw.print(ass.mTargetProcess);
15803                        pw.print("/");
15804                        UserHandle.formatUid(pw, ass.mTargetUid);
15805                        pw.print(" <- ");
15806                        pw.print(ass.mSourceProcess);
15807                        pw.print("/");
15808                        UserHandle.formatUid(pw, ass.mSourceUid);
15809                        pw.println();
15810                        pw.print("    via ");
15811                        pw.print(ass.mTargetComponent.flattenToShortString());
15812                        pw.println();
15813                        pw.print("    ");
15814                        long dur = ass.mTime;
15815                        if (ass.mNesting > 0) {
15816                            dur += now - ass.mStartTime;
15817                        }
15818                        TimeUtils.formatDuration(dur, pw);
15819                        pw.print(" (");
15820                        pw.print(ass.mCount);
15821                        pw.print(" times)");
15822                        pw.print("  ");
15823                        for (int i=0; i<ass.mStateTimes.length; i++) {
15824                            long amt = ass.mStateTimes[i];
15825                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15826                                amt += now - ass.mLastStateUptime;
15827                            }
15828                            if (amt != 0) {
15829                                pw.print(" ");
15830                                pw.print(ProcessList.makeProcStateString(
15831                                            i + ActivityManager.MIN_PROCESS_STATE));
15832                                pw.print("=");
15833                                TimeUtils.formatDuration(amt, pw);
15834                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15835                                    pw.print("*");
15836                                }
15837                            }
15838                        }
15839                        pw.println();
15840                        if (ass.mNesting > 0) {
15841                            pw.print("    Currently active: ");
15842                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15843                            pw.println();
15844                        }
15845                    }
15846                }
15847            }
15848
15849        }
15850
15851        if (!printedAnything) {
15852            pw.println("  (nothing)");
15853        }
15854    }
15855
15856    boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
15857            String header, boolean needSep) {
15858        boolean printed = false;
15859        for (int i=0; i<uids.size(); i++) {
15860            UidRecord uidRec = uids.valueAt(i);
15861            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
15862                continue;
15863            }
15864            if (!printed) {
15865                printed = true;
15866                if (needSep) {
15867                    pw.println();
15868                }
15869                pw.print("  ");
15870                pw.println(header);
15871                needSep = true;
15872            }
15873            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15874            pw.print(": "); pw.println(uidRec);
15875        }
15876        return printed;
15877    }
15878
15879    boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
15880        if(counts != null) {
15881            pw.println(header);
15882            for (int i = 0; i < counts.size(); i++) {
15883                final int uid = counts.keyAt(i);
15884                final int binderCount = counts.valueAt(i);
15885                pw.print("    UID ");
15886                pw.print(uid);
15887                pw.print(", binder count = ");
15888                pw.print(binderCount);
15889                pw.print(", package(s)= ");
15890                final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
15891                if (pkgNames != null) {
15892                    for (int j = 0; j < pkgNames.length; j++) {
15893                        pw.print(pkgNames[j]);
15894                        pw.print("; ");
15895                    }
15896                } else {
15897                    pw.print("NO PACKAGE NAME FOUND");
15898                }
15899                pw.println();
15900            }
15901            pw.println();
15902            return true;
15903        }
15904        return false;
15905    }
15906
15907    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15908            int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
15909        boolean needSep = false;
15910        int numPers = 0;
15911
15912        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15913
15914        if (dumpAll) {
15915            final int NP = mProcessNames.getMap().size();
15916            for (int ip=0; ip<NP; ip++) {
15917                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15918                final int NA = procs.size();
15919                for (int ia=0; ia<NA; ia++) {
15920                    ProcessRecord r = procs.valueAt(ia);
15921                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15922                        continue;
15923                    }
15924                    if (!needSep) {
15925                        pw.println("  All known processes:");
15926                        needSep = true;
15927                    }
15928                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15929                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15930                        pw.print(" "); pw.println(r);
15931                    r.dump(pw, "    ");
15932                    if (r.persistent) {
15933                        numPers++;
15934                    }
15935                }
15936            }
15937        }
15938
15939        if (mIsolatedProcesses.size() > 0) {
15940            boolean printed = false;
15941            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15942                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15943                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15944                    continue;
15945                }
15946                if (!printed) {
15947                    if (needSep) {
15948                        pw.println();
15949                    }
15950                    pw.println("  Isolated process list (sorted by uid):");
15951                    printed = true;
15952                    needSep = true;
15953                }
15954                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15955                pw.println(r);
15956            }
15957        }
15958
15959        if (mActiveInstrumentation.size() > 0) {
15960            boolean printed = false;
15961            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15962                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15963                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15964                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15965                    continue;
15966                }
15967                if (!printed) {
15968                    if (needSep) {
15969                        pw.println();
15970                    }
15971                    pw.println("  Active instrumentation:");
15972                    printed = true;
15973                    needSep = true;
15974                }
15975                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15976                pw.println(ai);
15977                ai.dump(pw, "      ");
15978            }
15979        }
15980
15981        if (mActiveUids.size() > 0) {
15982            if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
15983                needSep = true;
15984            }
15985        }
15986        if (dumpAll) {
15987            if (mValidateUids.size() > 0) {
15988                if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
15989                        needSep)) {
15990                    needSep = true;
15991                }
15992            }
15993        }
15994
15995        if (mLruProcesses.size() > 0) {
15996            if (needSep) {
15997                pw.println();
15998            }
15999            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
16000                    pw.print(" total, non-act at ");
16001                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16002                    pw.print(", non-svc at ");
16003                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16004                    pw.println("):");
16005            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
16006            needSep = true;
16007        }
16008
16009        if (dumpAll || dumpPackage != null) {
16010            synchronized (mPidsSelfLocked) {
16011                boolean printed = false;
16012                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16013                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16014                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16015                        continue;
16016                    }
16017                    if (!printed) {
16018                        if (needSep) pw.println();
16019                        needSep = true;
16020                        pw.println("  PID mappings:");
16021                        printed = true;
16022                    }
16023                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
16024                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
16025                }
16026            }
16027        }
16028
16029        if (mImportantProcesses.size() > 0) {
16030            synchronized (mPidsSelfLocked) {
16031                boolean printed = false;
16032                for (int i = 0; i< mImportantProcesses.size(); i++) {
16033                    ProcessRecord r = mPidsSelfLocked.get(
16034                            mImportantProcesses.valueAt(i).pid);
16035                    if (dumpPackage != null && (r == null
16036                            || !r.pkgList.containsKey(dumpPackage))) {
16037                        continue;
16038                    }
16039                    if (!printed) {
16040                        if (needSep) pw.println();
16041                        needSep = true;
16042                        pw.println("  Foreground Processes:");
16043                        printed = true;
16044                    }
16045                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
16046                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
16047                }
16048            }
16049        }
16050
16051        if (mPersistentStartingProcesses.size() > 0) {
16052            if (needSep) pw.println();
16053            needSep = true;
16054            pw.println("  Persisent processes that are starting:");
16055            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
16056                    "Starting Norm", "Restarting PERS", dumpPackage);
16057        }
16058
16059        if (mRemovedProcesses.size() > 0) {
16060            if (needSep) pw.println();
16061            needSep = true;
16062            pw.println("  Processes that are being removed:");
16063            dumpProcessList(pw, this, mRemovedProcesses, "    ",
16064                    "Removed Norm", "Removed PERS", dumpPackage);
16065        }
16066
16067        if (mProcessesOnHold.size() > 0) {
16068            if (needSep) pw.println();
16069            needSep = true;
16070            pw.println("  Processes that are on old until the system is ready:");
16071            dumpProcessList(pw, this, mProcessesOnHold, "    ",
16072                    "OnHold Norm", "OnHold PERS", dumpPackage);
16073        }
16074
16075        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
16076
16077        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
16078
16079        if (dumpPackage == null) {
16080            pw.println();
16081            needSep = false;
16082            mUserController.dump(pw, dumpAll);
16083        }
16084        if (mHomeProcess != null && (dumpPackage == null
16085                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16086            if (needSep) {
16087                pw.println();
16088                needSep = false;
16089            }
16090            pw.println("  mHomeProcess: " + mHomeProcess);
16091        }
16092        if (mPreviousProcess != null && (dumpPackage == null
16093                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16094            if (needSep) {
16095                pw.println();
16096                needSep = false;
16097            }
16098            pw.println("  mPreviousProcess: " + mPreviousProcess);
16099        }
16100        if (dumpAll && (mPreviousProcess == null || dumpPackage == null
16101                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16102            StringBuilder sb = new StringBuilder(128);
16103            sb.append("  mPreviousProcessVisibleTime: ");
16104            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
16105            pw.println(sb);
16106        }
16107        if (mHeavyWeightProcess != null && (dumpPackage == null
16108                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16109            if (needSep) {
16110                pw.println();
16111                needSep = false;
16112            }
16113            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16114        }
16115        if (dumpAll && mPendingStarts.size() > 0) {
16116            if (needSep) pw.println();
16117            needSep = true;
16118            pw.println("  mPendingStarts: ");
16119            for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
16120                pw.println("    " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
16121            }
16122        }
16123        if (dumpPackage == null) {
16124            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
16125            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
16126        }
16127        if (dumpAll) {
16128            if (dumpPackage == null) {
16129                pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
16130            }
16131            if (mCompatModePackages.getPackages().size() > 0) {
16132                boolean printed = false;
16133                for (Map.Entry<String, Integer> entry
16134                        : mCompatModePackages.getPackages().entrySet()) {
16135                    String pkg = entry.getKey();
16136                    int mode = entry.getValue();
16137                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
16138                        continue;
16139                    }
16140                    if (!printed) {
16141                        pw.println("  mScreenCompatPackages:");
16142                        printed = true;
16143                    }
16144                    pw.print("    "); pw.print(pkg); pw.print(": ");
16145                            pw.print(mode); pw.println();
16146                }
16147            }
16148            final int NI = mUidObservers.getRegisteredCallbackCount();
16149            boolean printed = false;
16150            for (int i=0; i<NI; i++) {
16151                final UidObserverRegistration reg = (UidObserverRegistration)
16152                        mUidObservers.getRegisteredCallbackCookie(i);
16153                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
16154                    if (!printed) {
16155                        pw.println("  mUidObservers:");
16156                        printed = true;
16157                    }
16158                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
16159                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
16160                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
16161                        pw.print(" IDLE");
16162                    }
16163                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
16164                        pw.print(" ACT" );
16165                    }
16166                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
16167                        pw.print(" GONE");
16168                    }
16169                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
16170                        pw.print(" STATE");
16171                        pw.print(" (cut="); pw.print(reg.cutpoint);
16172                        pw.print(")");
16173                    }
16174                    pw.println();
16175                    if (reg.lastProcStates != null) {
16176                        final int NJ = reg.lastProcStates.size();
16177                        for (int j=0; j<NJ; j++) {
16178                            pw.print("      Last ");
16179                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
16180                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
16181                        }
16182                    }
16183                }
16184            }
16185            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
16186            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
16187            if (mPendingTempWhitelist.size() > 0) {
16188                pw.println("  mPendingTempWhitelist:");
16189                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
16190                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
16191                    pw.print("    ");
16192                    UserHandle.formatUid(pw, ptw.targetUid);
16193                    pw.print(": ");
16194                    TimeUtils.formatDuration(ptw.duration, pw);
16195                    pw.print(" ");
16196                    pw.println(ptw.tag);
16197                }
16198            }
16199        }
16200        if (dumpPackage == null) {
16201            pw.println("  mWakefulness="
16202                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
16203            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
16204            pw.println("  mSleeping=" + mSleeping);
16205            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
16206            if (mRunningVoice != null) {
16207                pw.println("  mRunningVoice=" + mRunningVoice);
16208                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
16209            }
16210            pw.println("  mVrController=" + mVrController);
16211        }
16212        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16213                || mOrigWaitForDebugger) {
16214            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16215                    || dumpPackage.equals(mOrigDebugApp)) {
16216                if (needSep) {
16217                    pw.println();
16218                    needSep = false;
16219                }
16220                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
16221                        + " mDebugTransient=" + mDebugTransient
16222                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
16223            }
16224        }
16225        if (mCurAppTimeTracker != null) {
16226            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
16227        }
16228        if (mMemWatchProcesses.getMap().size() > 0) {
16229            pw.println("  Mem watch processes:");
16230            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
16231                    = mMemWatchProcesses.getMap();
16232            for (int i=0; i<procs.size(); i++) {
16233                final String proc = procs.keyAt(i);
16234                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16235                for (int j=0; j<uids.size(); j++) {
16236                    if (needSep) {
16237                        pw.println();
16238                        needSep = false;
16239                    }
16240                    StringBuilder sb = new StringBuilder();
16241                    sb.append("    ").append(proc).append('/');
16242                    UserHandle.formatUid(sb, uids.keyAt(j));
16243                    Pair<Long, String> val = uids.valueAt(j);
16244                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
16245                    if (val.second != null) {
16246                        sb.append(", report to ").append(val.second);
16247                    }
16248                    pw.println(sb.toString());
16249                }
16250            }
16251            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
16252            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
16253            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
16254                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
16255        }
16256        if (mTrackAllocationApp != null) {
16257            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16258                if (needSep) {
16259                    pw.println();
16260                    needSep = false;
16261                }
16262                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
16263            }
16264        }
16265        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16266                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16267            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16268                if (needSep) {
16269                    pw.println();
16270                    needSep = false;
16271                }
16272                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16273                if (mProfilerInfo != null) {
16274                    pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16275                            mProfilerInfo.profileFd);
16276                    pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
16277                            " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16278                            " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16279                    pw.println("  mProfileType=" + mProfileType);
16280                }
16281            }
16282        }
16283        if (mNativeDebuggingApp != null) {
16284            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16285                if (needSep) {
16286                    pw.println();
16287                    needSep = false;
16288                }
16289                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16290            }
16291        }
16292        if (mAllowAppSwitchUids.size() > 0) {
16293            boolean printed = false;
16294            for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
16295                ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
16296                for (int j = 0; j < types.size(); j++) {
16297                    if (dumpPackage == null ||
16298                            UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
16299                        if (needSep) {
16300                            pw.println();
16301                            needSep = false;
16302                        }
16303                        if (!printed) {
16304                            pw.println("  mAllowAppSwitchUids:");
16305                            printed = true;
16306                        }
16307                        pw.print("    User ");
16308                        pw.print(mAllowAppSwitchUids.keyAt(i));
16309                        pw.print(": Type ");
16310                        pw.print(types.keyAt(j));
16311                        pw.print(" = ");
16312                        UserHandle.formatUid(pw, types.valueAt(j).intValue());
16313                        pw.println();
16314                    }
16315                }
16316            }
16317        }
16318        if (dumpPackage == null) {
16319            if (mAlwaysFinishActivities) {
16320                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16321            }
16322            if (mController != null) {
16323                pw.println("  mController=" + mController
16324                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16325            }
16326            if (dumpAll) {
16327                pw.println("  Total persistent processes: " + numPers);
16328                pw.println("  mProcessesReady=" + mProcessesReady
16329                        + " mSystemReady=" + mSystemReady
16330                        + " mBooted=" + mBooted
16331                        + " mFactoryTest=" + mFactoryTest);
16332                pw.println("  mBooting=" + mBooting
16333                        + " mCallFinishBooting=" + mCallFinishBooting
16334                        + " mBootAnimationComplete=" + mBootAnimationComplete);
16335                pw.print("  mLastPowerCheckUptime=");
16336                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16337                        pw.println("");
16338                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16339                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16340                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16341                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16342                        + " (" + mLruProcesses.size() + " total)"
16343                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16344                        + " mNumServiceProcs=" + mNumServiceProcs
16345                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16346                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16347                        + " mLastMemoryLevel=" + mLastMemoryLevel
16348                        + " mLastNumProcesses=" + mLastNumProcesses);
16349                long now = SystemClock.uptimeMillis();
16350                pw.print("  mLastIdleTime=");
16351                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
16352                        pw.print(" mLowRamSinceLastIdle=");
16353                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16354                        pw.println();
16355            }
16356        }
16357        pw.println("  mForceBackgroundCheck=" + mForceBackgroundCheck);
16358    }
16359
16360    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16361            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16362        if (mProcessesToGc.size() > 0) {
16363            boolean printed = false;
16364            long now = SystemClock.uptimeMillis();
16365            for (int i=0; i<mProcessesToGc.size(); i++) {
16366                ProcessRecord proc = mProcessesToGc.get(i);
16367                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16368                    continue;
16369                }
16370                if (!printed) {
16371                    if (needSep) pw.println();
16372                    needSep = true;
16373                    pw.println("  Processes that are waiting to GC:");
16374                    printed = true;
16375                }
16376                pw.print("    Process "); pw.println(proc);
16377                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16378                        pw.print(", last gced=");
16379                        pw.print(now-proc.lastRequestedGc);
16380                        pw.print(" ms ago, last lowMem=");
16381                        pw.print(now-proc.lastLowMemory);
16382                        pw.println(" ms ago");
16383
16384            }
16385        }
16386        return needSep;
16387    }
16388
16389    void printOomLevel(PrintWriter pw, String name, int adj) {
16390        pw.print("    ");
16391        if (adj >= 0) {
16392            pw.print(' ');
16393            if (adj < 10) pw.print(' ');
16394        } else {
16395            if (adj > -10) pw.print(' ');
16396        }
16397        pw.print(adj);
16398        pw.print(": ");
16399        pw.print(name);
16400        pw.print(" (");
16401        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16402        pw.println(")");
16403    }
16404
16405    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16406            int opti, boolean dumpAll) {
16407        boolean needSep = false;
16408
16409        if (mLruProcesses.size() > 0) {
16410            if (needSep) pw.println();
16411            needSep = true;
16412            pw.println("  OOM levels:");
16413            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16414            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16415            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16416            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16417            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16418            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16419            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16420            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16421            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16422            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16423            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16424            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16425            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16426            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16427
16428            if (needSep) pw.println();
16429            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16430                    pw.print(" total, non-act at ");
16431                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16432                    pw.print(", non-svc at ");
16433                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16434                    pw.println("):");
16435            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16436            needSep = true;
16437        }
16438
16439        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16440
16441        pw.println();
16442        pw.println("  mHomeProcess: " + mHomeProcess);
16443        pw.println("  mPreviousProcess: " + mPreviousProcess);
16444        if (mHeavyWeightProcess != null) {
16445            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16446        }
16447
16448        return true;
16449    }
16450
16451    /**
16452     * There are three ways to call this:
16453     *  - no provider specified: dump all the providers
16454     *  - a flattened component name that matched an existing provider was specified as the
16455     *    first arg: dump that one provider
16456     *  - the first arg isn't the flattened component name of an existing provider:
16457     *    dump all providers whose component contains the first arg as a substring
16458     */
16459    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16460            int opti, boolean dumpAll) {
16461        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16462    }
16463
16464    /**
16465     * Similar to the dumpProvider, but only dumps the first matching provider.
16466     * The provider is responsible for dumping as proto.
16467     */
16468    protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
16469            String[] args) {
16470        return mProviderMap.dumpProviderProto(fd, pw, name, args);
16471    }
16472
16473    static class ItemMatcher {
16474        ArrayList<ComponentName> components;
16475        ArrayList<String> strings;
16476        ArrayList<Integer> objects;
16477        boolean all;
16478
16479        ItemMatcher() {
16480            all = true;
16481        }
16482
16483        void build(String name) {
16484            ComponentName componentName = ComponentName.unflattenFromString(name);
16485            if (componentName != null) {
16486                if (components == null) {
16487                    components = new ArrayList<ComponentName>();
16488                }
16489                components.add(componentName);
16490                all = false;
16491            } else {
16492                int objectId = 0;
16493                // Not a '/' separated full component name; maybe an object ID?
16494                try {
16495                    objectId = Integer.parseInt(name, 16);
16496                    if (objects == null) {
16497                        objects = new ArrayList<Integer>();
16498                    }
16499                    objects.add(objectId);
16500                    all = false;
16501                } catch (RuntimeException e) {
16502                    // Not an integer; just do string match.
16503                    if (strings == null) {
16504                        strings = new ArrayList<String>();
16505                    }
16506                    strings.add(name);
16507                    all = false;
16508                }
16509            }
16510        }
16511
16512        int build(String[] args, int opti) {
16513            for (; opti<args.length; opti++) {
16514                String name = args[opti];
16515                if ("--".equals(name)) {
16516                    return opti+1;
16517                }
16518                build(name);
16519            }
16520            return opti;
16521        }
16522
16523        boolean match(Object object, ComponentName comp) {
16524            if (all) {
16525                return true;
16526            }
16527            if (components != null) {
16528                for (int i=0; i<components.size(); i++) {
16529                    if (components.get(i).equals(comp)) {
16530                        return true;
16531                    }
16532                }
16533            }
16534            if (objects != null) {
16535                for (int i=0; i<objects.size(); i++) {
16536                    if (System.identityHashCode(object) == objects.get(i)) {
16537                        return true;
16538                    }
16539                }
16540            }
16541            if (strings != null) {
16542                String flat = comp.flattenToString();
16543                for (int i=0; i<strings.size(); i++) {
16544                    if (flat.contains(strings.get(i))) {
16545                        return true;
16546                    }
16547                }
16548            }
16549            return false;
16550        }
16551    }
16552
16553    /**
16554     * There are three things that cmd can be:
16555     *  - a flattened component name that matches an existing activity
16556     *  - the cmd arg isn't the flattened component name of an existing activity:
16557     *    dump all activity whose component contains the cmd as a substring
16558     *  - A hex number of the ActivityRecord object instance.
16559     *
16560     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16561     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16562     */
16563    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16564            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16565        ArrayList<ActivityRecord> activities;
16566
16567        synchronized (this) {
16568            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16569                    dumpFocusedStackOnly);
16570        }
16571
16572        if (activities.size() <= 0) {
16573            return false;
16574        }
16575
16576        String[] newArgs = new String[args.length - opti];
16577        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16578
16579        TaskRecord lastTask = null;
16580        boolean needSep = false;
16581        for (int i=activities.size()-1; i>=0; i--) {
16582            ActivityRecord r = activities.get(i);
16583            if (needSep) {
16584                pw.println();
16585            }
16586            needSep = true;
16587            synchronized (this) {
16588                final TaskRecord task = r.getTask();
16589                if (lastTask != task) {
16590                    lastTask = task;
16591                    pw.print("TASK "); pw.print(lastTask.affinity);
16592                            pw.print(" id="); pw.print(lastTask.taskId);
16593                            pw.print(" userId="); pw.println(lastTask.userId);
16594                    if (dumpAll) {
16595                        lastTask.dump(pw, "  ");
16596                    }
16597                }
16598            }
16599            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16600        }
16601        return true;
16602    }
16603
16604    /**
16605     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16606     * there is a thread associated with the activity.
16607     */
16608    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16609            final ActivityRecord r, String[] args, boolean dumpAll) {
16610        String innerPrefix = prefix + "  ";
16611        synchronized (this) {
16612            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16613                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16614                    pw.print(" pid=");
16615                    if (r.app != null) pw.println(r.app.pid);
16616                    else pw.println("(not running)");
16617            if (dumpAll) {
16618                r.dump(pw, innerPrefix);
16619            }
16620        }
16621        if (r.app != null && r.app.thread != null) {
16622            // flush anything that is already in the PrintWriter since the thread is going
16623            // to write to the file descriptor directly
16624            pw.flush();
16625            try {
16626                TransferPipe tp = new TransferPipe();
16627                try {
16628                    r.app.thread.dumpActivity(tp.getWriteFd(),
16629                            r.appToken, innerPrefix, args);
16630                    tp.go(fd);
16631                } finally {
16632                    tp.kill();
16633                }
16634            } catch (IOException e) {
16635                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16636            } catch (RemoteException e) {
16637                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16638            }
16639        }
16640    }
16641
16642    void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
16643        if (mRegisteredReceivers.size() > 0) {
16644            Iterator it = mRegisteredReceivers.values().iterator();
16645            while (it.hasNext()) {
16646                ReceiverList r = (ReceiverList)it.next();
16647                r.writeToProto(proto, BroadcastProto.RECEIVER_LIST);
16648            }
16649        }
16650        mReceiverResolver.writeToProto(proto, BroadcastProto.RECEIVER_RESOLVER);
16651        for (BroadcastQueue q : mBroadcastQueues) {
16652            q.writeToProto(proto, BroadcastProto.BROADCAST_QUEUE);
16653        }
16654        for (int user=0; user<mStickyBroadcasts.size(); user++) {
16655            long token = proto.start(BroadcastProto.STICKY_BROADCASTS);
16656            proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
16657            for (Map.Entry<String, ArrayList<Intent>> ent
16658                    : mStickyBroadcasts.valueAt(user).entrySet()) {
16659                long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
16660                proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
16661                for (Intent intent : ent.getValue()) {
16662                    intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
16663                            false, true, true, false);
16664                }
16665                proto.end(actionToken);
16666            }
16667            proto.end(token);
16668        }
16669
16670        long handlerToken = proto.start(BroadcastProto.HANDLER);
16671        proto.write(BroadcastProto.MainHandler.HANDLER, mHandler.toString());
16672        mHandler.getLooper().writeToProto(proto, BroadcastProto.MainHandler.LOOPER);
16673        proto.end(handlerToken);
16674    }
16675
16676    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16677            int opti, boolean dumpAll, String dumpPackage) {
16678        boolean needSep = false;
16679        boolean onlyHistory = false;
16680        boolean printedAnything = false;
16681
16682        if ("history".equals(dumpPackage)) {
16683            if (opti < args.length && "-s".equals(args[opti])) {
16684                dumpAll = false;
16685            }
16686            onlyHistory = true;
16687            dumpPackage = null;
16688        }
16689
16690        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16691        if (!onlyHistory && dumpAll) {
16692            if (mRegisteredReceivers.size() > 0) {
16693                boolean printed = false;
16694                Iterator it = mRegisteredReceivers.values().iterator();
16695                while (it.hasNext()) {
16696                    ReceiverList r = (ReceiverList)it.next();
16697                    if (dumpPackage != null && (r.app == null ||
16698                            !dumpPackage.equals(r.app.info.packageName))) {
16699                        continue;
16700                    }
16701                    if (!printed) {
16702                        pw.println("  Registered Receivers:");
16703                        needSep = true;
16704                        printed = true;
16705                        printedAnything = true;
16706                    }
16707                    pw.print("  * "); pw.println(r);
16708                    r.dump(pw, "    ");
16709                }
16710            }
16711
16712            if (mReceiverResolver.dump(pw, needSep ?
16713                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16714                    "    ", dumpPackage, false, false)) {
16715                needSep = true;
16716                printedAnything = true;
16717            }
16718        }
16719
16720        for (BroadcastQueue q : mBroadcastQueues) {
16721            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16722            printedAnything |= needSep;
16723        }
16724
16725        needSep = true;
16726
16727        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16728            for (int user=0; user<mStickyBroadcasts.size(); user++) {
16729                if (needSep) {
16730                    pw.println();
16731                }
16732                needSep = true;
16733                printedAnything = true;
16734                pw.print("  Sticky broadcasts for user ");
16735                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16736                StringBuilder sb = new StringBuilder(128);
16737                for (Map.Entry<String, ArrayList<Intent>> ent
16738                        : mStickyBroadcasts.valueAt(user).entrySet()) {
16739                    pw.print("  * Sticky action "); pw.print(ent.getKey());
16740                    if (dumpAll) {
16741                        pw.println(":");
16742                        ArrayList<Intent> intents = ent.getValue();
16743                        final int N = intents.size();
16744                        for (int i=0; i<N; i++) {
16745                            sb.setLength(0);
16746                            sb.append("    Intent: ");
16747                            intents.get(i).toShortString(sb, false, true, false, false);
16748                            pw.println(sb.toString());
16749                            Bundle bundle = intents.get(i).getExtras();
16750                            if (bundle != null) {
16751                                pw.print("      ");
16752                                pw.println(bundle.toString());
16753                            }
16754                        }
16755                    } else {
16756                        pw.println("");
16757                    }
16758                }
16759            }
16760        }
16761
16762        if (!onlyHistory && dumpAll) {
16763            pw.println();
16764            for (BroadcastQueue queue : mBroadcastQueues) {
16765                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16766                        + queue.mBroadcastsScheduled);
16767            }
16768            pw.println("  mHandler:");
16769            mHandler.dump(new PrintWriterPrinter(pw), "    ");
16770            needSep = true;
16771            printedAnything = true;
16772        }
16773
16774        if (!printedAnything) {
16775            pw.println("  (nothing)");
16776        }
16777    }
16778
16779    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16780            int opti, boolean dumpAll, String dumpPackage) {
16781        if (mCurBroadcastStats == null) {
16782            return;
16783        }
16784
16785        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16786        final long now = SystemClock.elapsedRealtime();
16787        if (mLastBroadcastStats != null) {
16788            pw.print("  Last stats (from ");
16789            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16790            pw.print(" to ");
16791            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16792            pw.print(", ");
16793            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16794                    - mLastBroadcastStats.mStartUptime, pw);
16795            pw.println(" uptime):");
16796            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16797                pw.println("    (nothing)");
16798            }
16799            pw.println();
16800        }
16801        pw.print("  Current stats (from ");
16802        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16803        pw.print(" to now, ");
16804        TimeUtils.formatDuration(SystemClock.uptimeMillis()
16805                - mCurBroadcastStats.mStartUptime, pw);
16806        pw.println(" uptime):");
16807        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16808            pw.println("    (nothing)");
16809        }
16810    }
16811
16812    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16813            int opti, boolean fullCheckin, String dumpPackage) {
16814        if (mCurBroadcastStats == null) {
16815            return;
16816        }
16817
16818        if (mLastBroadcastStats != null) {
16819            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16820            if (fullCheckin) {
16821                mLastBroadcastStats = null;
16822                return;
16823            }
16824        }
16825        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16826        if (fullCheckin) {
16827            mCurBroadcastStats = null;
16828        }
16829    }
16830
16831    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16832            int opti, boolean dumpAll, String dumpPackage) {
16833        boolean needSep;
16834        boolean printedAnything = false;
16835
16836        ItemMatcher matcher = new ItemMatcher();
16837        matcher.build(args, opti);
16838
16839        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16840
16841        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16842        printedAnything |= needSep;
16843
16844        if (mLaunchingProviders.size() > 0) {
16845            boolean printed = false;
16846            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16847                ContentProviderRecord r = mLaunchingProviders.get(i);
16848                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16849                    continue;
16850                }
16851                if (!printed) {
16852                    if (needSep) pw.println();
16853                    needSep = true;
16854                    pw.println("  Launching content providers:");
16855                    printed = true;
16856                    printedAnything = true;
16857                }
16858                pw.print("  Launching #"); pw.print(i); pw.print(": ");
16859                        pw.println(r);
16860            }
16861        }
16862
16863        if (!printedAnything) {
16864            pw.println("  (nothing)");
16865        }
16866    }
16867
16868    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16869            int opti, boolean dumpAll, String dumpPackage) {
16870        boolean needSep = false;
16871        boolean printedAnything = false;
16872
16873        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16874
16875        if (mGrantedUriPermissions.size() > 0) {
16876            boolean printed = false;
16877            int dumpUid = -2;
16878            if (dumpPackage != null) {
16879                try {
16880                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16881                            MATCH_ANY_USER, 0);
16882                } catch (NameNotFoundException e) {
16883                    dumpUid = -1;
16884                }
16885            }
16886            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16887                int uid = mGrantedUriPermissions.keyAt(i);
16888                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16889                    continue;
16890                }
16891                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16892                if (!printed) {
16893                    if (needSep) pw.println();
16894                    needSep = true;
16895                    pw.println("  Granted Uri Permissions:");
16896                    printed = true;
16897                    printedAnything = true;
16898                }
16899                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16900                for (UriPermission perm : perms.values()) {
16901                    pw.print("    "); pw.println(perm);
16902                    if (dumpAll) {
16903                        perm.dump(pw, "      ");
16904                    }
16905                }
16906            }
16907        }
16908
16909        if (!printedAnything) {
16910            pw.println("  (nothing)");
16911        }
16912    }
16913
16914    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16915            int opti, boolean dumpAll, String dumpPackage) {
16916        boolean printed = false;
16917
16918        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16919
16920        if (mIntentSenderRecords.size() > 0) {
16921            // Organize these by package name, so they are easier to read.
16922            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16923            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16924            final Iterator<WeakReference<PendingIntentRecord>> it
16925                    = mIntentSenderRecords.values().iterator();
16926            while (it.hasNext()) {
16927                WeakReference<PendingIntentRecord> ref = it.next();
16928                PendingIntentRecord rec = ref != null ? ref.get() : null;
16929                if (rec == null) {
16930                    weakRefs.add(ref);
16931                    continue;
16932                }
16933                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16934                    continue;
16935                }
16936                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16937                if (list == null) {
16938                    list = new ArrayList<>();
16939                    byPackage.put(rec.key.packageName, list);
16940                }
16941                list.add(rec);
16942            }
16943            for (int i = 0; i < byPackage.size(); i++) {
16944                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16945                printed = true;
16946                pw.print("  * "); pw.print(byPackage.keyAt(i));
16947                pw.print(": "); pw.print(intents.size()); pw.println(" items");
16948                for (int j = 0; j < intents.size(); j++) {
16949                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16950                    if (dumpAll) {
16951                        intents.get(j).dump(pw, "      ");
16952                    }
16953                }
16954            }
16955            if (weakRefs.size() > 0) {
16956                printed = true;
16957                pw.println("  * WEAK REFS:");
16958                for (int i = 0; i < weakRefs.size(); i++) {
16959                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16960                }
16961            }
16962        }
16963
16964        if (!printed) {
16965            pw.println("  (nothing)");
16966        }
16967    }
16968
16969    private static final int dumpProcessList(PrintWriter pw,
16970            ActivityManagerService service, List list,
16971            String prefix, String normalLabel, String persistentLabel,
16972            String dumpPackage) {
16973        int numPers = 0;
16974        final int N = list.size()-1;
16975        for (int i=N; i>=0; i--) {
16976            ProcessRecord r = (ProcessRecord)list.get(i);
16977            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16978                continue;
16979            }
16980            pw.println(String.format("%s%s #%2d: %s",
16981                    prefix, (r.persistent ? persistentLabel : normalLabel),
16982                    i, r.toString()));
16983            if (r.persistent) {
16984                numPers++;
16985            }
16986        }
16987        return numPers;
16988    }
16989
16990    private static final boolean dumpProcessOomList(PrintWriter pw,
16991            ActivityManagerService service, List<ProcessRecord> origList,
16992            String prefix, String normalLabel, String persistentLabel,
16993            boolean inclDetails, String dumpPackage) {
16994
16995        ArrayList<Pair<ProcessRecord, Integer>> list
16996                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16997        for (int i=0; i<origList.size(); i++) {
16998            ProcessRecord r = origList.get(i);
16999            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17000                continue;
17001            }
17002            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
17003        }
17004
17005        if (list.size() <= 0) {
17006            return false;
17007        }
17008
17009        Comparator<Pair<ProcessRecord, Integer>> comparator
17010                = new Comparator<Pair<ProcessRecord, Integer>>() {
17011            @Override
17012            public int compare(Pair<ProcessRecord, Integer> object1,
17013                    Pair<ProcessRecord, Integer> object2) {
17014                if (object1.first.setAdj != object2.first.setAdj) {
17015                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
17016                }
17017                if (object1.first.setProcState != object2.first.setProcState) {
17018                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
17019                }
17020                if (object1.second.intValue() != object2.second.intValue()) {
17021                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
17022                }
17023                return 0;
17024            }
17025        };
17026
17027        Collections.sort(list, comparator);
17028
17029        final long curUptime = SystemClock.uptimeMillis();
17030        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
17031
17032        for (int i=list.size()-1; i>=0; i--) {
17033            ProcessRecord r = list.get(i).first;
17034            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
17035            char schedGroup;
17036            switch (r.setSchedGroup) {
17037                case ProcessList.SCHED_GROUP_BACKGROUND:
17038                    schedGroup = 'B';
17039                    break;
17040                case ProcessList.SCHED_GROUP_DEFAULT:
17041                    schedGroup = 'F';
17042                    break;
17043                case ProcessList.SCHED_GROUP_TOP_APP:
17044                    schedGroup = 'T';
17045                    break;
17046                default:
17047                    schedGroup = '?';
17048                    break;
17049            }
17050            char foreground;
17051            if (r.foregroundActivities) {
17052                foreground = 'A';
17053            } else if (r.foregroundServices) {
17054                foreground = 'S';
17055            } else {
17056                foreground = ' ';
17057            }
17058            String procState = ProcessList.makeProcStateString(r.curProcState);
17059            pw.print(prefix);
17060            pw.print(r.persistent ? persistentLabel : normalLabel);
17061            pw.print(" #");
17062            int num = (origList.size()-1)-list.get(i).second;
17063            if (num < 10) pw.print(' ');
17064            pw.print(num);
17065            pw.print(": ");
17066            pw.print(oomAdj);
17067            pw.print(' ');
17068            pw.print(schedGroup);
17069            pw.print('/');
17070            pw.print(foreground);
17071            pw.print('/');
17072            pw.print(procState);
17073            pw.print(" trm:");
17074            if (r.trimMemoryLevel < 10) pw.print(' ');
17075            pw.print(r.trimMemoryLevel);
17076            pw.print(' ');
17077            pw.print(r.toShortString());
17078            pw.print(" (");
17079            pw.print(r.adjType);
17080            pw.println(')');
17081            if (r.adjSource != null || r.adjTarget != null) {
17082                pw.print(prefix);
17083                pw.print("    ");
17084                if (r.adjTarget instanceof ComponentName) {
17085                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
17086                } else if (r.adjTarget != null) {
17087                    pw.print(r.adjTarget.toString());
17088                } else {
17089                    pw.print("{null}");
17090                }
17091                pw.print("<=");
17092                if (r.adjSource instanceof ProcessRecord) {
17093                    pw.print("Proc{");
17094                    pw.print(((ProcessRecord)r.adjSource).toShortString());
17095                    pw.println("}");
17096                } else if (r.adjSource != null) {
17097                    pw.println(r.adjSource.toString());
17098                } else {
17099                    pw.println("{null}");
17100                }
17101            }
17102            if (inclDetails) {
17103                pw.print(prefix);
17104                pw.print("    ");
17105                pw.print("oom: max="); pw.print(r.maxAdj);
17106                pw.print(" curRaw="); pw.print(r.curRawAdj);
17107                pw.print(" setRaw="); pw.print(r.setRawAdj);
17108                pw.print(" cur="); pw.print(r.curAdj);
17109                pw.print(" set="); pw.println(r.setAdj);
17110                pw.print(prefix);
17111                pw.print("    ");
17112                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
17113                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
17114                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
17115                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
17116                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
17117                pw.println();
17118                pw.print(prefix);
17119                pw.print("    ");
17120                pw.print("cached="); pw.print(r.cached);
17121                pw.print(" empty="); pw.print(r.empty);
17122                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
17123
17124                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
17125                    if (r.lastCpuTime != 0) {
17126                        long timeUsed = r.curCpuTime - r.lastCpuTime;
17127                        pw.print(prefix);
17128                        pw.print("    ");
17129                        pw.print("run cpu over ");
17130                        TimeUtils.formatDuration(uptimeSince, pw);
17131                        pw.print(" used ");
17132                        TimeUtils.formatDuration(timeUsed, pw);
17133                        pw.print(" (");
17134                        pw.print((timeUsed*100)/uptimeSince);
17135                        pw.println("%)");
17136                    }
17137                }
17138            }
17139        }
17140        return true;
17141    }
17142
17143    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
17144            String[] args) {
17145        ArrayList<ProcessRecord> procs;
17146        synchronized (this) {
17147            if (args != null && args.length > start
17148                    && args[start].charAt(0) != '-') {
17149                procs = new ArrayList<ProcessRecord>();
17150                int pid = -1;
17151                try {
17152                    pid = Integer.parseInt(args[start]);
17153                } catch (NumberFormatException e) {
17154                }
17155                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17156                    ProcessRecord proc = mLruProcesses.get(i);
17157                    if (proc.pid > 0 && proc.pid == pid) {
17158                        procs.add(proc);
17159                    } else if (allPkgs && proc.pkgList != null
17160                            && proc.pkgList.containsKey(args[start])) {
17161                        procs.add(proc);
17162                    } else if (proc.processName.equals(args[start])) {
17163                        procs.add(proc);
17164                    }
17165                }
17166                if (procs.size() <= 0) {
17167                    return null;
17168                }
17169            } else {
17170                procs = new ArrayList<ProcessRecord>(mLruProcesses);
17171            }
17172        }
17173        return procs;
17174    }
17175
17176    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
17177            PrintWriter pw, String[] args) {
17178        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
17179        if (procs == null) {
17180            pw.println("No process found for: " + args[0]);
17181            return;
17182        }
17183
17184        long uptime = SystemClock.uptimeMillis();
17185        long realtime = SystemClock.elapsedRealtime();
17186        pw.println("Applications Graphics Acceleration Info:");
17187        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17188
17189        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17190            ProcessRecord r = procs.get(i);
17191            if (r.thread != null) {
17192                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
17193                pw.flush();
17194                try {
17195                    TransferPipe tp = new TransferPipe();
17196                    try {
17197                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
17198                        tp.go(fd);
17199                    } finally {
17200                        tp.kill();
17201                    }
17202                } catch (IOException e) {
17203                    pw.println("Failure while dumping the app: " + r);
17204                    pw.flush();
17205                } catch (RemoteException e) {
17206                    pw.println("Got a RemoteException while dumping the app " + r);
17207                    pw.flush();
17208                }
17209            }
17210        }
17211    }
17212
17213    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
17214        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
17215        if (procs == null) {
17216            pw.println("No process found for: " + args[0]);
17217            return;
17218        }
17219
17220        pw.println("Applications Database Info:");
17221
17222        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17223            ProcessRecord r = procs.get(i);
17224            if (r.thread != null) {
17225                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
17226                pw.flush();
17227                try {
17228                    TransferPipe tp = new TransferPipe();
17229                    try {
17230                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
17231                        tp.go(fd);
17232                    } finally {
17233                        tp.kill();
17234                    }
17235                } catch (IOException e) {
17236                    pw.println("Failure while dumping the app: " + r);
17237                    pw.flush();
17238                } catch (RemoteException e) {
17239                    pw.println("Got a RemoteException while dumping the app " + r);
17240                    pw.flush();
17241                }
17242            }
17243        }
17244    }
17245
17246    final static class MemItem {
17247        final boolean isProc;
17248        final String label;
17249        final String shortLabel;
17250        final long pss;
17251        final long swapPss;
17252        final int id;
17253        final boolean hasActivities;
17254        ArrayList<MemItem> subitems;
17255
17256        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
17257                boolean _hasActivities) {
17258            isProc = true;
17259            label = _label;
17260            shortLabel = _shortLabel;
17261            pss = _pss;
17262            swapPss = _swapPss;
17263            id = _id;
17264            hasActivities = _hasActivities;
17265        }
17266
17267        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
17268            isProc = false;
17269            label = _label;
17270            shortLabel = _shortLabel;
17271            pss = _pss;
17272            swapPss = _swapPss;
17273            id = _id;
17274            hasActivities = false;
17275        }
17276    }
17277
17278    private static void sortMemItems(List<MemItem> items) {
17279        Collections.sort(items, new Comparator<MemItem>() {
17280            @Override
17281            public int compare(MemItem lhs, MemItem rhs) {
17282                if (lhs.pss < rhs.pss) {
17283                    return 1;
17284                } else if (lhs.pss > rhs.pss) {
17285                    return -1;
17286                }
17287                return 0;
17288            }
17289        });
17290    }
17291
17292    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
17293            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
17294        if (sort && !isCompact) {
17295            sortMemItems(items);
17296        }
17297
17298        for (int i=0; i<items.size(); i++) {
17299            MemItem mi = items.get(i);
17300            if (!isCompact) {
17301                if (dumpSwapPss) {
17302                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
17303                            mi.label, stringifyKBSize(mi.swapPss));
17304                } else {
17305                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
17306                }
17307            } else if (mi.isProc) {
17308                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
17309                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
17310                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
17311                pw.println(mi.hasActivities ? ",a" : ",e");
17312            } else {
17313                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
17314                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
17315            }
17316            if (mi.subitems != null) {
17317                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
17318                        true, isCompact, dumpSwapPss);
17319            }
17320        }
17321    }
17322
17323    static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
17324            ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
17325        if (sort) {
17326            sortMemItems(items);
17327        }
17328
17329        for (int i=0; i<items.size(); i++) {
17330            MemItem mi = items.get(i);
17331            final long token = proto.start(fieldId);
17332
17333            proto.write(MemInfoProto.MemItem.TAG, tag);
17334            proto.write(MemInfoProto.MemItem.LABEL, mi.shortLabel);
17335            proto.write(MemInfoProto.MemItem.IS_PROC, mi.isProc);
17336            proto.write(MemInfoProto.MemItem.ID, mi.id);
17337            proto.write(MemInfoProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
17338            proto.write(MemInfoProto.MemItem.PSS_KB, mi.pss);
17339            if (dumpSwapPss) {
17340                proto.write(MemInfoProto.MemItem.SWAP_PSS_KB, mi.swapPss);
17341            }
17342            if (mi.subitems != null) {
17343                dumpMemItems(proto, MemInfoProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
17344                        true, dumpSwapPss);
17345            }
17346            proto.end(token);
17347        }
17348    }
17349
17350    // These are in KB.
17351    static final long[] DUMP_MEM_BUCKETS = new long[] {
17352        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
17353        120*1024, 160*1024, 200*1024,
17354        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
17355        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
17356    };
17357
17358    static final void appendMemBucket(StringBuilder out, long memKB, String label,
17359            boolean stackLike) {
17360        int start = label.lastIndexOf('.');
17361        if (start >= 0) start++;
17362        else start = 0;
17363        int end = label.length();
17364        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
17365            if (DUMP_MEM_BUCKETS[i] >= memKB) {
17366                long bucket = DUMP_MEM_BUCKETS[i]/1024;
17367                out.append(bucket);
17368                out.append(stackLike ? "MB." : "MB ");
17369                out.append(label, start, end);
17370                return;
17371            }
17372        }
17373        out.append(memKB/1024);
17374        out.append(stackLike ? "MB." : "MB ");
17375        out.append(label, start, end);
17376    }
17377
17378    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17379            ProcessList.NATIVE_ADJ,
17380            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17381            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17382            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17383            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17384            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17385            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17386    };
17387    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17388            "Native",
17389            "System", "Persistent", "Persistent Service", "Foreground",
17390            "Visible", "Perceptible",
17391            "Heavy Weight", "Backup",
17392            "A Services", "Home",
17393            "Previous", "B Services", "Cached"
17394    };
17395    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17396            "native",
17397            "sys", "pers", "persvc", "fore",
17398            "vis", "percept",
17399            "heavy", "backup",
17400            "servicea", "home",
17401            "prev", "serviceb", "cached"
17402    };
17403
17404    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17405            long realtime, boolean isCheckinRequest, boolean isCompact) {
17406        if (isCompact) {
17407            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17408        }
17409        if (isCheckinRequest || isCompact) {
17410            // short checkin version
17411            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17412        } else {
17413            pw.println("Applications Memory Usage (in Kilobytes):");
17414            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17415        }
17416    }
17417
17418    private static final int KSM_SHARED = 0;
17419    private static final int KSM_SHARING = 1;
17420    private static final int KSM_UNSHARED = 2;
17421    private static final int KSM_VOLATILE = 3;
17422
17423    private final long[] getKsmInfo() {
17424        long[] longOut = new long[4];
17425        final int[] SINGLE_LONG_FORMAT = new int[] {
17426            PROC_SPACE_TERM| PROC_OUT_LONG
17427        };
17428        long[] longTmp = new long[1];
17429        readProcFile("/sys/kernel/mm/ksm/pages_shared",
17430                SINGLE_LONG_FORMAT, null, longTmp, null);
17431        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17432        longTmp[0] = 0;
17433        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17434                SINGLE_LONG_FORMAT, null, longTmp, null);
17435        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17436        longTmp[0] = 0;
17437        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17438                SINGLE_LONG_FORMAT, null, longTmp, null);
17439        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17440        longTmp[0] = 0;
17441        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17442                SINGLE_LONG_FORMAT, null, longTmp, null);
17443        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17444        return longOut;
17445    }
17446
17447    private static String stringifySize(long size, int order) {
17448        Locale locale = Locale.US;
17449        switch (order) {
17450            case 1:
17451                return String.format(locale, "%,13d", size);
17452            case 1024:
17453                return String.format(locale, "%,9dK", size / 1024);
17454            case 1024 * 1024:
17455                return String.format(locale, "%,5dM", size / 1024 / 1024);
17456            case 1024 * 1024 * 1024:
17457                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17458            default:
17459                throw new IllegalArgumentException("Invalid size order");
17460        }
17461    }
17462
17463    private static String stringifyKBSize(long size) {
17464        return stringifySize(size * 1024, 1024);
17465    }
17466
17467    // Update this version number if you change the 'compact' format.
17468    private static final int MEMINFO_COMPACT_VERSION = 1;
17469
17470    private static class MemoryUsageDumpOptions {
17471        boolean dumpDetails;
17472        boolean dumpFullDetails;
17473        boolean dumpDalvik;
17474        boolean dumpSummaryOnly;
17475        boolean dumpUnreachable;
17476        boolean oomOnly;
17477        boolean isCompact;
17478        boolean localOnly;
17479        boolean packages;
17480        boolean isCheckinRequest;
17481        boolean dumpSwapPss;
17482        boolean dumpProto;
17483    }
17484
17485    final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
17486            String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) {
17487        MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions();
17488        opts.dumpDetails = false;
17489        opts.dumpFullDetails = false;
17490        opts.dumpDalvik = false;
17491        opts.dumpSummaryOnly = false;
17492        opts.dumpUnreachable = false;
17493        opts.oomOnly = false;
17494        opts.isCompact = false;
17495        opts.localOnly = false;
17496        opts.packages = false;
17497        opts.isCheckinRequest = false;
17498        opts.dumpSwapPss = false;
17499        opts.dumpProto = asProto;
17500
17501        int opti = 0;
17502        while (opti < args.length) {
17503            String opt = args[opti];
17504            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17505                break;
17506            }
17507            opti++;
17508            if ("-a".equals(opt)) {
17509                opts.dumpDetails = true;
17510                opts.dumpFullDetails = true;
17511                opts.dumpDalvik = true;
17512                opts.dumpSwapPss = true;
17513            } else if ("-d".equals(opt)) {
17514                opts.dumpDalvik = true;
17515            } else if ("-c".equals(opt)) {
17516                opts.isCompact = true;
17517            } else if ("-s".equals(opt)) {
17518                opts.dumpDetails = true;
17519                opts.dumpSummaryOnly = true;
17520            } else if ("-S".equals(opt)) {
17521                opts.dumpSwapPss = true;
17522            } else if ("--unreachable".equals(opt)) {
17523                opts.dumpUnreachable = true;
17524            } else if ("--oom".equals(opt)) {
17525                opts.oomOnly = true;
17526            } else if ("--local".equals(opt)) {
17527                opts.localOnly = true;
17528            } else if ("--package".equals(opt)) {
17529                opts.packages = true;
17530            } else if ("--checkin".equals(opt)) {
17531                opts.isCheckinRequest = true;
17532            } else if ("--proto".equals(opt)) {
17533                opts.dumpProto = true;
17534
17535            } else if ("-h".equals(opt)) {
17536                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17537                pw.println("  -a: include all available information for each process.");
17538                pw.println("  -d: include dalvik details.");
17539                pw.println("  -c: dump in a compact machine-parseable representation.");
17540                pw.println("  -s: dump only summary of application memory usage.");
17541                pw.println("  -S: dump also SwapPss.");
17542                pw.println("  --oom: only show processes organized by oom adj.");
17543                pw.println("  --local: only collect details locally, don't call process.");
17544                pw.println("  --package: interpret process arg as package, dumping all");
17545                pw.println("             processes that have loaded that package.");
17546                pw.println("  --checkin: dump data for a checkin");
17547                pw.println("  --proto: dump data to proto");
17548                pw.println("If [process] is specified it can be the name or ");
17549                pw.println("pid of a specific process to dump.");
17550                return;
17551            } else {
17552                pw.println("Unknown argument: " + opt + "; use -h for help");
17553            }
17554        }
17555
17556        String[] innerArgs = new String[args.length-opti];
17557        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17558
17559        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
17560        if (opts.dumpProto) {
17561            dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
17562        } else {
17563            dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
17564        }
17565    }
17566
17567    private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
17568            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
17569            ArrayList<ProcessRecord> procs, PrintWriter categoryPw) {
17570        long uptime = SystemClock.uptimeMillis();
17571        long realtime = SystemClock.elapsedRealtime();
17572        final long[] tmpLong = new long[1];
17573
17574        if (procs == null) {
17575            // No Java processes.  Maybe they want to print a native process.
17576            String proc = "N/A";
17577            if (innerArgs.length > 0) {
17578                proc = innerArgs[0];
17579                if (proc.charAt(0) != '-') {
17580                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
17581                            = new ArrayList<ProcessCpuTracker.Stats>();
17582                    updateCpuStatsNow();
17583                    int findPid = -1;
17584                    try {
17585                        findPid = Integer.parseInt(innerArgs[0]);
17586                    } catch (NumberFormatException e) {
17587                    }
17588                    synchronized (mProcessCpuTracker) {
17589                        final int N = mProcessCpuTracker.countStats();
17590                        for (int i=0; i<N; i++) {
17591                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17592                            if (st.pid == findPid || (st.baseName != null
17593                                    && st.baseName.equals(innerArgs[0]))) {
17594                                nativeProcs.add(st);
17595                            }
17596                        }
17597                    }
17598                    if (nativeProcs.size() > 0) {
17599                        dumpApplicationMemoryUsageHeader(pw, uptime, realtime,
17600                                opts.isCheckinRequest, opts.isCompact);
17601                        Debug.MemoryInfo mi = null;
17602                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17603                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17604                            final int pid = r.pid;
17605                            if (!opts.isCheckinRequest && opts.dumpDetails) {
17606                                pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17607                            }
17608                            if (mi == null) {
17609                                mi = new Debug.MemoryInfo();
17610                            }
17611                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
17612                                Debug.getMemoryInfo(pid, mi);
17613                            } else {
17614                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17615                                mi.dalvikPrivateDirty = (int)tmpLong[0];
17616                            }
17617                            ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest,
17618                                    opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
17619                                    pid, r.baseName, 0, 0, 0, 0, 0, 0);
17620                            if (opts.isCheckinRequest) {
17621                                pw.println();
17622                            }
17623                        }
17624                        return;
17625                    }
17626                }
17627            }
17628            pw.println("No process found for: " + proc);
17629            return;
17630        }
17631
17632        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
17633            opts.dumpDetails = true;
17634        }
17635
17636        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
17637
17638        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17639        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17640        long nativePss = 0;
17641        long nativeSwapPss = 0;
17642        long dalvikPss = 0;
17643        long dalvikSwapPss = 0;
17644        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17645                EmptyArray.LONG;
17646        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17647                EmptyArray.LONG;
17648        long otherPss = 0;
17649        long otherSwapPss = 0;
17650        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17651        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17652
17653        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17654        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17655        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17656                new ArrayList[DUMP_MEM_OOM_LABEL.length];
17657
17658        long totalPss = 0;
17659        long totalSwapPss = 0;
17660        long cachedPss = 0;
17661        long cachedSwapPss = 0;
17662        boolean hasSwapPss = false;
17663
17664        Debug.MemoryInfo mi = null;
17665        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17666            final ProcessRecord r = procs.get(i);
17667            final IApplicationThread thread;
17668            final int pid;
17669            final int oomAdj;
17670            final boolean hasActivities;
17671            synchronized (this) {
17672                thread = r.thread;
17673                pid = r.pid;
17674                oomAdj = r.getSetAdjWithServices();
17675                hasActivities = r.activities.size() > 0;
17676            }
17677            if (thread != null) {
17678                if (!opts.isCheckinRequest && opts.dumpDetails) {
17679                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17680                }
17681                if (mi == null) {
17682                    mi = new Debug.MemoryInfo();
17683                }
17684                final int reportType;
17685                final long startTime;
17686                final long endTime;
17687                if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
17688                    reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
17689                    startTime = SystemClock.currentThreadTimeMillis();
17690                    Debug.getMemoryInfo(pid, mi);
17691                    endTime = SystemClock.currentThreadTimeMillis();
17692                    hasSwapPss = mi.hasSwappedOutPss;
17693                } else {
17694                    reportType = ProcessStats.ADD_PSS_EXTERNAL;
17695                    startTime = SystemClock.currentThreadTimeMillis();
17696                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17697                    endTime = SystemClock.currentThreadTimeMillis();
17698                    mi.dalvikPrivateDirty = (int)tmpLong[0];
17699                }
17700                if (opts.dumpDetails) {
17701                    if (opts.localOnly) {
17702                        ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
17703                                opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17704                        if (opts.isCheckinRequest) {
17705                            pw.println();
17706                        }
17707                    } else {
17708                        pw.flush();
17709                        try {
17710                            TransferPipe tp = new TransferPipe();
17711                            try {
17712                                thread.dumpMemInfo(tp.getWriteFd(),
17713                                        mi, opts.isCheckinRequest, opts.dumpFullDetails,
17714                                        opts.dumpDalvik, opts.dumpSummaryOnly, opts.dumpUnreachable, innerArgs);
17715                                tp.go(fd);
17716                            } finally {
17717                                tp.kill();
17718                            }
17719                        } catch (IOException e) {
17720                            if (!opts.isCheckinRequest) {
17721                                pw.println("Got IoException! " + e);
17722                                pw.flush();
17723                            }
17724                        } catch (RemoteException e) {
17725                            if (!opts.isCheckinRequest) {
17726                                pw.println("Got RemoteException! " + e);
17727                                pw.flush();
17728                            }
17729                        }
17730                    }
17731                }
17732
17733                final long myTotalPss = mi.getTotalPss();
17734                final long myTotalUss = mi.getTotalUss();
17735                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17736
17737                synchronized (this) {
17738                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17739                        // Record this for posterity if the process has been stable.
17740                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true,
17741                                reportType, endTime-startTime, r.pkgList);
17742                    }
17743                }
17744
17745                if (!opts.isCheckinRequest && mi != null) {
17746                    totalPss += myTotalPss;
17747                    totalSwapPss += myTotalSwapPss;
17748                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17749                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17750                            myTotalSwapPss, pid, hasActivities);
17751                    procMems.add(pssItem);
17752                    procMemsMap.put(pid, pssItem);
17753
17754                    nativePss += mi.nativePss;
17755                    nativeSwapPss += mi.nativeSwappedOutPss;
17756                    dalvikPss += mi.dalvikPss;
17757                    dalvikSwapPss += mi.dalvikSwappedOutPss;
17758                    for (int j=0; j<dalvikSubitemPss.length; j++) {
17759                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17760                        dalvikSubitemSwapPss[j] +=
17761                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17762                    }
17763                    otherPss += mi.otherPss;
17764                    otherSwapPss += mi.otherSwappedOutPss;
17765                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17766                        long mem = mi.getOtherPss(j);
17767                        miscPss[j] += mem;
17768                        otherPss -= mem;
17769                        mem = mi.getOtherSwappedOutPss(j);
17770                        miscSwapPss[j] += mem;
17771                        otherSwapPss -= mem;
17772                    }
17773
17774                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17775                        cachedPss += myTotalPss;
17776                        cachedSwapPss += myTotalSwapPss;
17777                    }
17778
17779                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17780                        if (oomIndex == (oomPss.length - 1)
17781                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17782                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17783                            oomPss[oomIndex] += myTotalPss;
17784                            oomSwapPss[oomIndex] += myTotalSwapPss;
17785                            if (oomProcs[oomIndex] == null) {
17786                                oomProcs[oomIndex] = new ArrayList<MemItem>();
17787                            }
17788                            oomProcs[oomIndex].add(pssItem);
17789                            break;
17790                        }
17791                    }
17792                }
17793            }
17794        }
17795
17796        long nativeProcTotalPss = 0;
17797
17798        if (!opts.isCheckinRequest && procs.size() > 1 && !opts.packages) {
17799            // If we are showing aggregations, also look for native processes to
17800            // include so that our aggregations are more accurate.
17801            updateCpuStatsNow();
17802            mi = null;
17803            synchronized (mProcessCpuTracker) {
17804                final int N = mProcessCpuTracker.countStats();
17805                for (int i=0; i<N; i++) {
17806                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17807                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17808                        if (mi == null) {
17809                            mi = new Debug.MemoryInfo();
17810                        }
17811                        if (!brief && !opts.oomOnly) {
17812                            Debug.getMemoryInfo(st.pid, mi);
17813                        } else {
17814                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17815                            mi.nativePrivateDirty = (int)tmpLong[0];
17816                        }
17817
17818                        final long myTotalPss = mi.getTotalPss();
17819                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17820                        totalPss += myTotalPss;
17821                        nativeProcTotalPss += myTotalPss;
17822
17823                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17824                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17825                        procMems.add(pssItem);
17826
17827                        nativePss += mi.nativePss;
17828                        nativeSwapPss += mi.nativeSwappedOutPss;
17829                        dalvikPss += mi.dalvikPss;
17830                        dalvikSwapPss += mi.dalvikSwappedOutPss;
17831                        for (int j=0; j<dalvikSubitemPss.length; j++) {
17832                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17833                            dalvikSubitemSwapPss[j] +=
17834                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17835                        }
17836                        otherPss += mi.otherPss;
17837                        otherSwapPss += mi.otherSwappedOutPss;
17838                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17839                            long mem = mi.getOtherPss(j);
17840                            miscPss[j] += mem;
17841                            otherPss -= mem;
17842                            mem = mi.getOtherSwappedOutPss(j);
17843                            miscSwapPss[j] += mem;
17844                            otherSwapPss -= mem;
17845                        }
17846                        oomPss[0] += myTotalPss;
17847                        oomSwapPss[0] += myTotalSwapPss;
17848                        if (oomProcs[0] == null) {
17849                            oomProcs[0] = new ArrayList<MemItem>();
17850                        }
17851                        oomProcs[0].add(pssItem);
17852                    }
17853                }
17854            }
17855
17856            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17857
17858            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17859            final int dalvikId = -2;
17860            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17861            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17862            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17863                String label = Debug.MemoryInfo.getOtherLabel(j);
17864                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17865            }
17866            if (dalvikSubitemPss.length > 0) {
17867                // Add dalvik subitems.
17868                for (MemItem memItem : catMems) {
17869                    int memItemStart = 0, memItemEnd = 0;
17870                    if (memItem.id == dalvikId) {
17871                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17872                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17873                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17874                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17875                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17876                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17877                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17878                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17879                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17880                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17881                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17882                    } else {
17883                        continue;  // No subitems, continue.
17884                    }
17885                    memItem.subitems = new ArrayList<MemItem>();
17886                    for (int j=memItemStart; j<=memItemEnd; j++) {
17887                        final String name = Debug.MemoryInfo.getOtherLabel(
17888                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
17889                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17890                                dalvikSubitemSwapPss[j], j));
17891                    }
17892                }
17893            }
17894
17895            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17896            for (int j=0; j<oomPss.length; j++) {
17897                if (oomPss[j] != 0) {
17898                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17899                            : DUMP_MEM_OOM_LABEL[j];
17900                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17901                            DUMP_MEM_OOM_ADJ[j]);
17902                    item.subitems = oomProcs[j];
17903                    oomMems.add(item);
17904                }
17905            }
17906
17907            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17908            if (!brief && !opts.oomOnly && !opts.isCompact) {
17909                pw.println();
17910                pw.println("Total PSS by process:");
17911                dumpMemItems(pw, "  ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
17912                pw.println();
17913            }
17914            if (!opts.isCompact) {
17915                pw.println("Total PSS by OOM adjustment:");
17916            }
17917            dumpMemItems(pw, "  ", "oom", oomMems, false, opts.isCompact, opts.dumpSwapPss);
17918            if (!brief && !opts.oomOnly) {
17919                PrintWriter out = categoryPw != null ? categoryPw : pw;
17920                if (!opts.isCompact) {
17921                    out.println();
17922                    out.println("Total PSS by category:");
17923                }
17924                dumpMemItems(out, "  ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
17925            }
17926            if (!opts.isCompact) {
17927                pw.println();
17928            }
17929            MemInfoReader memInfo = new MemInfoReader();
17930            memInfo.readMemInfo();
17931            if (nativeProcTotalPss > 0) {
17932                synchronized (this) {
17933                    final long cachedKb = memInfo.getCachedSizeKb();
17934                    final long freeKb = memInfo.getFreeSizeKb();
17935                    final long zramKb = memInfo.getZramTotalSizeKb();
17936                    final long kernelKb = memInfo.getKernelUsedSizeKb();
17937                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17938                            kernelKb*1024, nativeProcTotalPss*1024);
17939                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17940                            nativeProcTotalPss);
17941                }
17942            }
17943            if (!brief) {
17944                if (!opts.isCompact) {
17945                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17946                    pw.print(" (status ");
17947                    switch (mLastMemoryLevel) {
17948                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17949                            pw.println("normal)");
17950                            break;
17951                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17952                            pw.println("moderate)");
17953                            break;
17954                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
17955                            pw.println("low)");
17956                            break;
17957                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17958                            pw.println("critical)");
17959                            break;
17960                        default:
17961                            pw.print(mLastMemoryLevel);
17962                            pw.println(")");
17963                            break;
17964                    }
17965                    pw.print(" Free RAM: ");
17966                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17967                            + memInfo.getFreeSizeKb()));
17968                    pw.print(" (");
17969                    pw.print(stringifyKBSize(cachedPss));
17970                    pw.print(" cached pss + ");
17971                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17972                    pw.print(" cached kernel + ");
17973                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17974                    pw.println(" free)");
17975                } else {
17976                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17977                    pw.print(cachedPss + memInfo.getCachedSizeKb()
17978                            + memInfo.getFreeSizeKb()); pw.print(",");
17979                    pw.println(totalPss - cachedPss);
17980                }
17981            }
17982            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17983                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17984                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17985            if (!opts.isCompact) {
17986                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17987                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17988                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17989                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17990                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17991            } else {
17992                pw.print("lostram,"); pw.println(lostRAM);
17993            }
17994            if (!brief) {
17995                if (memInfo.getZramTotalSizeKb() != 0) {
17996                    if (!opts.isCompact) {
17997                        pw.print("     ZRAM: ");
17998                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17999                                pw.print(" physical used for ");
18000                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
18001                                        - memInfo.getSwapFreeSizeKb()));
18002                                pw.print(" in swap (");
18003                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
18004                                pw.println(" total swap)");
18005                    } else {
18006                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
18007                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
18008                                pw.println(memInfo.getSwapFreeSizeKb());
18009                    }
18010                }
18011                final long[] ksm = getKsmInfo();
18012                if (!opts.isCompact) {
18013                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
18014                            || ksm[KSM_VOLATILE] != 0) {
18015                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
18016                                pw.print(" saved from shared ");
18017                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
18018                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
18019                                pw.print(" unshared; ");
18020                                pw.print(stringifyKBSize(
18021                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
18022                    }
18023                    pw.print("   Tuning: ");
18024                    pw.print(ActivityManager.staticGetMemoryClass());
18025                    pw.print(" (large ");
18026                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18027                    pw.print("), oom ");
18028                    pw.print(stringifySize(
18029                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
18030                    pw.print(", restore limit ");
18031                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
18032                    if (ActivityManager.isLowRamDeviceStatic()) {
18033                        pw.print(" (low-ram)");
18034                    }
18035                    if (ActivityManager.isHighEndGfx()) {
18036                        pw.print(" (high-end-gfx)");
18037                    }
18038                    pw.println();
18039                } else {
18040                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
18041                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
18042                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
18043                    pw.print("tuning,");
18044                    pw.print(ActivityManager.staticGetMemoryClass());
18045                    pw.print(',');
18046                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18047                    pw.print(',');
18048                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
18049                    if (ActivityManager.isLowRamDeviceStatic()) {
18050                        pw.print(",low-ram");
18051                    }
18052                    if (ActivityManager.isHighEndGfx()) {
18053                        pw.print(",high-end-gfx");
18054                    }
18055                    pw.println();
18056                }
18057            }
18058        }
18059    }
18060
18061    private final void dumpApplicationMemoryUsage(FileDescriptor fd,
18062            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18063            ArrayList<ProcessRecord> procs) {
18064        final long uptimeMs = SystemClock.uptimeMillis();
18065        final long realtimeMs = SystemClock.elapsedRealtime();
18066        final long[] tmpLong = new long[1];
18067
18068        if (procs == null) {
18069            // No Java processes.  Maybe they want to print a native process.
18070            String proc = "N/A";
18071            if (innerArgs.length > 0) {
18072                proc = innerArgs[0];
18073                if (proc.charAt(0) != '-') {
18074                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
18075                            = new ArrayList<ProcessCpuTracker.Stats>();
18076                    updateCpuStatsNow();
18077                    int findPid = -1;
18078                    try {
18079                        findPid = Integer.parseInt(innerArgs[0]);
18080                    } catch (NumberFormatException e) {
18081                    }
18082                    synchronized (mProcessCpuTracker) {
18083                        final int N = mProcessCpuTracker.countStats();
18084                        for (int i=0; i<N; i++) {
18085                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18086                            if (st.pid == findPid || (st.baseName != null
18087                                    && st.baseName.equals(innerArgs[0]))) {
18088                                nativeProcs.add(st);
18089                            }
18090                        }
18091                    }
18092                    if (nativeProcs.size() > 0) {
18093                        ProtoOutputStream proto = new ProtoOutputStream(fd);
18094
18095                        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
18096                        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
18097                        Debug.MemoryInfo mi = null;
18098                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18099                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18100                            final int pid = r.pid;
18101                            final long nToken = proto.start(MemInfoProto.NATIVE_PROCESSES);
18102
18103                            proto.write(MemInfoProto.ProcessMemory.PID, pid);
18104                            proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.baseName);
18105
18106                            if (mi == null) {
18107                                mi = new Debug.MemoryInfo();
18108                            }
18109                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18110                                Debug.getMemoryInfo(pid, mi);
18111                            } else {
18112                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18113                                mi.dalvikPrivateDirty = (int)tmpLong[0];
18114                            }
18115                            ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
18116                                    opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
18117
18118                            proto.end(nToken);
18119                        }
18120
18121                        proto.flush();
18122                        return;
18123                    }
18124                }
18125            }
18126            Log.d(TAG, "No process found for: " + innerArgs[0]);
18127            return;
18128        }
18129
18130        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18131            opts.dumpDetails = true;
18132        }
18133
18134        ProtoOutputStream proto = new ProtoOutputStream(fd);
18135
18136        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
18137        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
18138
18139        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18140        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18141        long nativePss = 0;
18142        long nativeSwapPss = 0;
18143        long dalvikPss = 0;
18144        long dalvikSwapPss = 0;
18145        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18146                EmptyArray.LONG;
18147        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18148                EmptyArray.LONG;
18149        long otherPss = 0;
18150        long otherSwapPss = 0;
18151        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18152        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18153
18154        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18155        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18156        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18157                new ArrayList[DUMP_MEM_OOM_LABEL.length];
18158
18159        long totalPss = 0;
18160        long totalSwapPss = 0;
18161        long cachedPss = 0;
18162        long cachedSwapPss = 0;
18163        boolean hasSwapPss = false;
18164
18165        Debug.MemoryInfo mi = null;
18166        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18167            final ProcessRecord r = procs.get(i);
18168            final IApplicationThread thread;
18169            final int pid;
18170            final int oomAdj;
18171            final boolean hasActivities;
18172            synchronized (this) {
18173                thread = r.thread;
18174                pid = r.pid;
18175                oomAdj = r.getSetAdjWithServices();
18176                hasActivities = r.activities.size() > 0;
18177            }
18178            if (thread == null) {
18179                continue;
18180            }
18181            if (mi == null) {
18182                mi = new Debug.MemoryInfo();
18183            }
18184            final int reportType;
18185            final long startTime;
18186            final long endTime;
18187            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18188                reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
18189                startTime = SystemClock.currentThreadTimeMillis();
18190                Debug.getMemoryInfo(pid, mi);
18191                endTime = SystemClock.currentThreadTimeMillis();
18192                hasSwapPss = mi.hasSwappedOutPss;
18193            } else {
18194                reportType = ProcessStats.ADD_PSS_EXTERNAL;
18195                startTime = SystemClock.currentThreadTimeMillis();
18196                mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
18197                endTime = SystemClock.currentThreadTimeMillis();
18198                mi.dalvikPrivateDirty = (int) tmpLong[0];
18199            }
18200            if (opts.dumpDetails) {
18201                if (opts.localOnly) {
18202                    final long aToken = proto.start(MemInfoProto.APP_PROCESSES);
18203                    final long mToken = proto.start(MemInfoProto.AppData.PROCESS_MEMORY);
18204                    proto.write(MemInfoProto.ProcessMemory.PID, pid);
18205                    proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.processName);
18206                    ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
18207                            opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
18208                    proto.end(mToken);
18209                    proto.end(aToken);
18210                } else {
18211                    try {
18212                        ByteTransferPipe tp = new ByteTransferPipe();
18213                        try {
18214                            thread.dumpMemInfoProto(tp.getWriteFd(),
18215                                mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18216                                opts.dumpUnreachable, innerArgs);
18217                            proto.write(MemInfoProto.APP_PROCESSES, tp.get());
18218                        } finally {
18219                            tp.kill();
18220                        }
18221                    } catch (IOException e) {
18222                        Log.e(TAG, "Got IOException!", e);
18223                    } catch (RemoteException e) {
18224                        Log.e(TAG, "Got RemoteException!", e);
18225                    }
18226                }
18227            }
18228
18229            final long myTotalPss = mi.getTotalPss();
18230            final long myTotalUss = mi.getTotalUss();
18231            final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18232
18233            synchronized (this) {
18234                if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
18235                    // Record this for posterity if the process has been stable.
18236                    r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true,
18237                            reportType, endTime-startTime, r.pkgList);
18238                }
18239            }
18240
18241            if (!opts.isCheckinRequest && mi != null) {
18242                totalPss += myTotalPss;
18243                totalSwapPss += myTotalSwapPss;
18244                MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
18245                        (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
18246                        myTotalSwapPss, pid, hasActivities);
18247                procMems.add(pssItem);
18248                procMemsMap.put(pid, pssItem);
18249
18250                nativePss += mi.nativePss;
18251                nativeSwapPss += mi.nativeSwappedOutPss;
18252                dalvikPss += mi.dalvikPss;
18253                dalvikSwapPss += mi.dalvikSwappedOutPss;
18254                for (int j=0; j<dalvikSubitemPss.length; j++) {
18255                    dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18256                    dalvikSubitemSwapPss[j] +=
18257                            mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18258                }
18259                otherPss += mi.otherPss;
18260                otherSwapPss += mi.otherSwappedOutPss;
18261                for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18262                    long mem = mi.getOtherPss(j);
18263                    miscPss[j] += mem;
18264                    otherPss -= mem;
18265                    mem = mi.getOtherSwappedOutPss(j);
18266                    miscSwapPss[j] += mem;
18267                    otherSwapPss -= mem;
18268                }
18269
18270                if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
18271                    cachedPss += myTotalPss;
18272                    cachedSwapPss += myTotalSwapPss;
18273                }
18274
18275                for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
18276                    if (oomIndex == (oomPss.length - 1)
18277                            || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
18278                                    && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
18279                        oomPss[oomIndex] += myTotalPss;
18280                        oomSwapPss[oomIndex] += myTotalSwapPss;
18281                        if (oomProcs[oomIndex] == null) {
18282                            oomProcs[oomIndex] = new ArrayList<MemItem>();
18283                        }
18284                        oomProcs[oomIndex].add(pssItem);
18285                        break;
18286                    }
18287                }
18288            }
18289        }
18290
18291        long nativeProcTotalPss = 0;
18292
18293        if (procs.size() > 1 && !opts.packages) {
18294            // If we are showing aggregations, also look for native processes to
18295            // include so that our aggregations are more accurate.
18296            updateCpuStatsNow();
18297            mi = null;
18298            synchronized (mProcessCpuTracker) {
18299                final int N = mProcessCpuTracker.countStats();
18300                for (int i=0; i<N; i++) {
18301                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18302                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
18303                        if (mi == null) {
18304                            mi = new Debug.MemoryInfo();
18305                        }
18306                        if (!brief && !opts.oomOnly) {
18307                            Debug.getMemoryInfo(st.pid, mi);
18308                        } else {
18309                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
18310                            mi.nativePrivateDirty = (int)tmpLong[0];
18311                        }
18312
18313                        final long myTotalPss = mi.getTotalPss();
18314                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18315                        totalPss += myTotalPss;
18316                        nativeProcTotalPss += myTotalPss;
18317
18318                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
18319                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
18320                        procMems.add(pssItem);
18321
18322                        nativePss += mi.nativePss;
18323                        nativeSwapPss += mi.nativeSwappedOutPss;
18324                        dalvikPss += mi.dalvikPss;
18325                        dalvikSwapPss += mi.dalvikSwappedOutPss;
18326                        for (int j=0; j<dalvikSubitemPss.length; j++) {
18327                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18328                            dalvikSubitemSwapPss[j] +=
18329                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18330                        }
18331                        otherPss += mi.otherPss;
18332                        otherSwapPss += mi.otherSwappedOutPss;
18333                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18334                            long mem = mi.getOtherPss(j);
18335                            miscPss[j] += mem;
18336                            otherPss -= mem;
18337                            mem = mi.getOtherSwappedOutPss(j);
18338                            miscSwapPss[j] += mem;
18339                            otherSwapPss -= mem;
18340                        }
18341                        oomPss[0] += myTotalPss;
18342                        oomSwapPss[0] += myTotalSwapPss;
18343                        if (oomProcs[0] == null) {
18344                            oomProcs[0] = new ArrayList<MemItem>();
18345                        }
18346                        oomProcs[0].add(pssItem);
18347                    }
18348                }
18349            }
18350
18351            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
18352
18353            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
18354            final int dalvikId = -2;
18355            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
18356            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
18357            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18358                String label = Debug.MemoryInfo.getOtherLabel(j);
18359                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
18360            }
18361            if (dalvikSubitemPss.length > 0) {
18362                // Add dalvik subitems.
18363                for (MemItem memItem : catMems) {
18364                    int memItemStart = 0, memItemEnd = 0;
18365                    if (memItem.id == dalvikId) {
18366                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
18367                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
18368                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
18369                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
18370                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
18371                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
18372                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
18373                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
18374                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
18375                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
18376                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
18377                    } else {
18378                        continue;  // No subitems, continue.
18379                    }
18380                    memItem.subitems = new ArrayList<MemItem>();
18381                    for (int j=memItemStart; j<=memItemEnd; j++) {
18382                        final String name = Debug.MemoryInfo.getOtherLabel(
18383                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
18384                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
18385                                dalvikSubitemSwapPss[j], j));
18386                    }
18387                }
18388            }
18389
18390            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
18391            for (int j=0; j<oomPss.length; j++) {
18392                if (oomPss[j] != 0) {
18393                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
18394                            : DUMP_MEM_OOM_LABEL[j];
18395                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
18396                            DUMP_MEM_OOM_ADJ[j]);
18397                    item.subitems = oomProcs[j];
18398                    oomMems.add(item);
18399                }
18400            }
18401
18402            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
18403            if (!opts.oomOnly) {
18404                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_PROCESS, "proc",
18405                        procMems, true, opts.dumpSwapPss);
18406            }
18407            dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
18408                    oomMems, false, opts.dumpSwapPss);
18409            if (!brief && !opts.oomOnly) {
18410                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_CATEGORY, "cat",
18411                        catMems, true, opts.dumpSwapPss);
18412            }
18413            MemInfoReader memInfo = new MemInfoReader();
18414            memInfo.readMemInfo();
18415            if (nativeProcTotalPss > 0) {
18416                synchronized (this) {
18417                    final long cachedKb = memInfo.getCachedSizeKb();
18418                    final long freeKb = memInfo.getFreeSizeKb();
18419                    final long zramKb = memInfo.getZramTotalSizeKb();
18420                    final long kernelKb = memInfo.getKernelUsedSizeKb();
18421                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
18422                            kernelKb*1024, nativeProcTotalPss*1024);
18423                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
18424                            nativeProcTotalPss);
18425                }
18426            }
18427            if (!brief) {
18428                proto.write(MemInfoProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
18429                proto.write(MemInfoProto.STATUS, mLastMemoryLevel);
18430                proto.write(MemInfoProto.CACHED_PSS_KB, cachedPss);
18431                proto.write(MemInfoProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
18432                proto.write(MemInfoProto.FREE_KB, memInfo.getFreeSizeKb());
18433            }
18434            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
18435                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
18436                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
18437            proto.write(MemInfoProto.USED_PSS_KB, totalPss - cachedPss);
18438            proto.write(MemInfoProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
18439            proto.write(MemInfoProto.LOST_RAM_KB, lostRAM);
18440            if (!brief) {
18441                if (memInfo.getZramTotalSizeKb() != 0) {
18442                    proto.write(MemInfoProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
18443                    proto.write(MemInfoProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
18444                            memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
18445                    proto.write(MemInfoProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
18446                }
18447                final long[] ksm = getKsmInfo();
18448                proto.write(MemInfoProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
18449                proto.write(MemInfoProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
18450                proto.write(MemInfoProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
18451                proto.write(MemInfoProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
18452
18453                proto.write(MemInfoProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
18454                proto.write(MemInfoProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
18455                proto.write(MemInfoProto.OOM_KB,
18456                        mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
18457                proto.write(MemInfoProto.RESTORE_LIMIT_KB,
18458                        mProcessList.getCachedRestoreThresholdKb());
18459
18460                proto.write(MemInfoProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
18461                proto.write(MemInfoProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
18462            }
18463        }
18464
18465        proto.flush();
18466    }
18467
18468    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
18469            long memtrack, String name) {
18470        sb.append("  ");
18471        sb.append(ProcessList.makeOomAdjString(oomAdj));
18472        sb.append(' ');
18473        sb.append(ProcessList.makeProcStateString(procState));
18474        sb.append(' ');
18475        ProcessList.appendRamKb(sb, pss);
18476        sb.append(": ");
18477        sb.append(name);
18478        if (memtrack > 0) {
18479            sb.append(" (");
18480            sb.append(stringifyKBSize(memtrack));
18481            sb.append(" memtrack)");
18482        }
18483    }
18484
18485    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
18486        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
18487        sb.append(" (pid ");
18488        sb.append(mi.pid);
18489        sb.append(") ");
18490        sb.append(mi.adjType);
18491        sb.append('\n');
18492        if (mi.adjReason != null) {
18493            sb.append("                      ");
18494            sb.append(mi.adjReason);
18495            sb.append('\n');
18496        }
18497    }
18498
18499    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
18500        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
18501        for (int i=0, N=memInfos.size(); i<N; i++) {
18502            ProcessMemInfo mi = memInfos.get(i);
18503            infoMap.put(mi.pid, mi);
18504        }
18505        updateCpuStatsNow();
18506        long[] memtrackTmp = new long[1];
18507        final List<ProcessCpuTracker.Stats> stats;
18508        // Get a list of Stats that have vsize > 0
18509        synchronized (mProcessCpuTracker) {
18510            stats = mProcessCpuTracker.getStats((st) -> {
18511                return st.vsize > 0;
18512            });
18513        }
18514        final int statsCount = stats.size();
18515        for (int i = 0; i < statsCount; i++) {
18516            ProcessCpuTracker.Stats st = stats.get(i);
18517            long pss = Debug.getPss(st.pid, null, memtrackTmp);
18518            if (pss > 0) {
18519                if (infoMap.indexOfKey(st.pid) < 0) {
18520                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
18521                            ProcessList.NATIVE_ADJ, -1, "native", null);
18522                    mi.pss = pss;
18523                    mi.memtrack = memtrackTmp[0];
18524                    memInfos.add(mi);
18525                }
18526            }
18527        }
18528
18529        long totalPss = 0;
18530        long totalMemtrack = 0;
18531        for (int i=0, N=memInfos.size(); i<N; i++) {
18532            ProcessMemInfo mi = memInfos.get(i);
18533            if (mi.pss == 0) {
18534                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
18535                mi.memtrack = memtrackTmp[0];
18536            }
18537            totalPss += mi.pss;
18538            totalMemtrack += mi.memtrack;
18539        }
18540        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
18541            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
18542                if (lhs.oomAdj != rhs.oomAdj) {
18543                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
18544                }
18545                if (lhs.pss != rhs.pss) {
18546                    return lhs.pss < rhs.pss ? 1 : -1;
18547                }
18548                return 0;
18549            }
18550        });
18551
18552        StringBuilder tag = new StringBuilder(128);
18553        StringBuilder stack = new StringBuilder(128);
18554        tag.append("Low on memory -- ");
18555        appendMemBucket(tag, totalPss, "total", false);
18556        appendMemBucket(stack, totalPss, "total", true);
18557
18558        StringBuilder fullNativeBuilder = new StringBuilder(1024);
18559        StringBuilder shortNativeBuilder = new StringBuilder(1024);
18560        StringBuilder fullJavaBuilder = new StringBuilder(1024);
18561
18562        boolean firstLine = true;
18563        int lastOomAdj = Integer.MIN_VALUE;
18564        long extraNativeRam = 0;
18565        long extraNativeMemtrack = 0;
18566        long cachedPss = 0;
18567        for (int i=0, N=memInfos.size(); i<N; i++) {
18568            ProcessMemInfo mi = memInfos.get(i);
18569
18570            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
18571                cachedPss += mi.pss;
18572            }
18573
18574            if (mi.oomAdj != ProcessList.NATIVE_ADJ
18575                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
18576                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
18577                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
18578                if (lastOomAdj != mi.oomAdj) {
18579                    lastOomAdj = mi.oomAdj;
18580                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18581                        tag.append(" / ");
18582                    }
18583                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
18584                        if (firstLine) {
18585                            stack.append(":");
18586                            firstLine = false;
18587                        }
18588                        stack.append("\n\t at ");
18589                    } else {
18590                        stack.append("$");
18591                    }
18592                } else {
18593                    tag.append(" ");
18594                    stack.append("$");
18595                }
18596                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18597                    appendMemBucket(tag, mi.pss, mi.name, false);
18598                }
18599                appendMemBucket(stack, mi.pss, mi.name, true);
18600                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
18601                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
18602                    stack.append("(");
18603                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
18604                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
18605                            stack.append(DUMP_MEM_OOM_LABEL[k]);
18606                            stack.append(":");
18607                            stack.append(DUMP_MEM_OOM_ADJ[k]);
18608                        }
18609                    }
18610                    stack.append(")");
18611                }
18612            }
18613
18614            appendMemInfo(fullNativeBuilder, mi);
18615            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
18616                // The short form only has native processes that are >= 512K.
18617                if (mi.pss >= 512) {
18618                    appendMemInfo(shortNativeBuilder, mi);
18619                } else {
18620                    extraNativeRam += mi.pss;
18621                    extraNativeMemtrack += mi.memtrack;
18622                }
18623            } else {
18624                // Short form has all other details, but if we have collected RAM
18625                // from smaller native processes let's dump a summary of that.
18626                if (extraNativeRam > 0) {
18627                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
18628                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
18629                    shortNativeBuilder.append('\n');
18630                    extraNativeRam = 0;
18631                }
18632                appendMemInfo(fullJavaBuilder, mi);
18633            }
18634        }
18635
18636        fullJavaBuilder.append("           ");
18637        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
18638        fullJavaBuilder.append(": TOTAL");
18639        if (totalMemtrack > 0) {
18640            fullJavaBuilder.append(" (");
18641            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
18642            fullJavaBuilder.append(" memtrack)");
18643        } else {
18644        }
18645        fullJavaBuilder.append("\n");
18646
18647        MemInfoReader memInfo = new MemInfoReader();
18648        memInfo.readMemInfo();
18649        final long[] infos = memInfo.getRawInfo();
18650
18651        StringBuilder memInfoBuilder = new StringBuilder(1024);
18652        Debug.getMemInfo(infos);
18653        memInfoBuilder.append("  MemInfo: ");
18654        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
18655        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
18656        memInfoBuilder.append(stringifyKBSize(
18657                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
18658        memInfoBuilder.append(stringifyKBSize(
18659                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
18660        memInfoBuilder.append(stringifyKBSize(
18661                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
18662        memInfoBuilder.append("           ");
18663        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
18664        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
18665        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
18666        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
18667        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
18668            memInfoBuilder.append("  ZRAM: ");
18669            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
18670            memInfoBuilder.append(" RAM, ");
18671            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
18672            memInfoBuilder.append(" swap total, ");
18673            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
18674            memInfoBuilder.append(" swap free\n");
18675        }
18676        final long[] ksm = getKsmInfo();
18677        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
18678                || ksm[KSM_VOLATILE] != 0) {
18679            memInfoBuilder.append("  KSM: ");
18680            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
18681            memInfoBuilder.append(" saved from shared ");
18682            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
18683            memInfoBuilder.append("\n       ");
18684            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
18685            memInfoBuilder.append(" unshared; ");
18686            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
18687            memInfoBuilder.append(" volatile\n");
18688        }
18689        memInfoBuilder.append("  Free RAM: ");
18690        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
18691                + memInfo.getFreeSizeKb()));
18692        memInfoBuilder.append("\n");
18693        memInfoBuilder.append("  Used RAM: ");
18694        memInfoBuilder.append(stringifyKBSize(
18695                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
18696        memInfoBuilder.append("\n");
18697        memInfoBuilder.append("  Lost RAM: ");
18698        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
18699                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
18700                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
18701        memInfoBuilder.append("\n");
18702        Slog.i(TAG, "Low on memory:");
18703        Slog.i(TAG, shortNativeBuilder.toString());
18704        Slog.i(TAG, fullJavaBuilder.toString());
18705        Slog.i(TAG, memInfoBuilder.toString());
18706
18707        StringBuilder dropBuilder = new StringBuilder(1024);
18708        /*
18709        StringWriter oomSw = new StringWriter();
18710        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
18711        StringWriter catSw = new StringWriter();
18712        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
18713        String[] emptyArgs = new String[] { };
18714        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
18715        oomPw.flush();
18716        String oomString = oomSw.toString();
18717        */
18718        dropBuilder.append("Low on memory:");
18719        dropBuilder.append(stack);
18720        dropBuilder.append('\n');
18721        dropBuilder.append(fullNativeBuilder);
18722        dropBuilder.append(fullJavaBuilder);
18723        dropBuilder.append('\n');
18724        dropBuilder.append(memInfoBuilder);
18725        dropBuilder.append('\n');
18726        /*
18727        dropBuilder.append(oomString);
18728        dropBuilder.append('\n');
18729        */
18730        StringWriter catSw = new StringWriter();
18731        synchronized (ActivityManagerService.this) {
18732            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
18733            String[] emptyArgs = new String[] { };
18734            catPw.println();
18735            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
18736            catPw.println();
18737            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
18738                    false, null).dumpLocked();
18739            catPw.println();
18740            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
18741            catPw.flush();
18742        }
18743        dropBuilder.append(catSw.toString());
18744        addErrorToDropBox("lowmem", null, "system_server", null,
18745                null, tag.toString(), dropBuilder.toString(), null, null);
18746        //Slog.i(TAG, "Sent to dropbox:");
18747        //Slog.i(TAG, dropBuilder.toString());
18748        synchronized (ActivityManagerService.this) {
18749            long now = SystemClock.uptimeMillis();
18750            if (mLastMemUsageReportTime < now) {
18751                mLastMemUsageReportTime = now;
18752            }
18753        }
18754    }
18755
18756    /**
18757     * Searches array of arguments for the specified string
18758     * @param args array of argument strings
18759     * @param value value to search for
18760     * @return true if the value is contained in the array
18761     */
18762    private static boolean scanArgs(String[] args, String value) {
18763        if (args != null) {
18764            for (String arg : args) {
18765                if (value.equals(arg)) {
18766                    return true;
18767                }
18768            }
18769        }
18770        return false;
18771    }
18772
18773    private final boolean removeDyingProviderLocked(ProcessRecord proc,
18774            ContentProviderRecord cpr, boolean always) {
18775        final boolean inLaunching = mLaunchingProviders.contains(cpr);
18776
18777        if (!inLaunching || always) {
18778            synchronized (cpr) {
18779                cpr.launchingApp = null;
18780                cpr.notifyAll();
18781            }
18782            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
18783            String names[] = cpr.info.authority.split(";");
18784            for (int j = 0; j < names.length; j++) {
18785                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
18786            }
18787        }
18788
18789        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
18790            ContentProviderConnection conn = cpr.connections.get(i);
18791            if (conn.waiting) {
18792                // If this connection is waiting for the provider, then we don't
18793                // need to mess with its process unless we are always removing
18794                // or for some reason the provider is not currently launching.
18795                if (inLaunching && !always) {
18796                    continue;
18797                }
18798            }
18799            ProcessRecord capp = conn.client;
18800            conn.dead = true;
18801            if (conn.stableCount > 0) {
18802                if (!capp.persistent && capp.thread != null
18803                        && capp.pid != 0
18804                        && capp.pid != MY_PID) {
18805                    capp.kill("depends on provider "
18806                            + cpr.name.flattenToShortString()
18807                            + " in dying proc " + (proc != null ? proc.processName : "??")
18808                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
18809                }
18810            } else if (capp.thread != null && conn.provider.provider != null) {
18811                try {
18812                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
18813                } catch (RemoteException e) {
18814                }
18815                // In the protocol here, we don't expect the client to correctly
18816                // clean up this connection, we'll just remove it.
18817                cpr.connections.remove(i);
18818                if (conn.client.conProviders.remove(conn)) {
18819                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
18820                }
18821            }
18822        }
18823
18824        if (inLaunching && always) {
18825            mLaunchingProviders.remove(cpr);
18826        }
18827        return inLaunching;
18828    }
18829
18830    /**
18831     * Main code for cleaning up a process when it has gone away.  This is
18832     * called both as a result of the process dying, or directly when stopping
18833     * a process when running in single process mode.
18834     *
18835     * @return Returns true if the given process has been restarted, so the
18836     * app that was passed in must remain on the process lists.
18837     */
18838    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18839            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18840        if (index >= 0) {
18841            removeLruProcessLocked(app);
18842            ProcessList.remove(app.pid);
18843        }
18844
18845        mProcessesToGc.remove(app);
18846        mPendingPssProcesses.remove(app);
18847
18848        // Dismiss any open dialogs.
18849        if (app.crashDialog != null && !app.forceCrashReport) {
18850            app.crashDialog.dismiss();
18851            app.crashDialog = null;
18852        }
18853        if (app.anrDialog != null) {
18854            app.anrDialog.dismiss();
18855            app.anrDialog = null;
18856        }
18857        if (app.waitDialog != null) {
18858            app.waitDialog.dismiss();
18859            app.waitDialog = null;
18860        }
18861
18862        app.crashing = false;
18863        app.notResponding = false;
18864
18865        app.resetPackageList(mProcessStats);
18866        app.unlinkDeathRecipient();
18867        app.makeInactive(mProcessStats);
18868        app.waitingToKill = null;
18869        app.forcingToImportant = null;
18870        updateProcessForegroundLocked(app, false, false);
18871        app.foregroundActivities = false;
18872        app.hasShownUi = false;
18873        app.treatLikeActivity = false;
18874        app.hasAboveClient = false;
18875        app.hasClientActivities = false;
18876
18877        mServices.killServicesLocked(app, allowRestart);
18878
18879        boolean restart = false;
18880
18881        // Remove published content providers.
18882        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18883            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18884            final boolean always = app.bad || !allowRestart;
18885            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18886            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18887                // We left the provider in the launching list, need to
18888                // restart it.
18889                restart = true;
18890            }
18891
18892            cpr.provider = null;
18893            cpr.proc = null;
18894        }
18895        app.pubProviders.clear();
18896
18897        // Take care of any launching providers waiting for this process.
18898        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18899            restart = true;
18900        }
18901
18902        // Unregister from connected content providers.
18903        if (!app.conProviders.isEmpty()) {
18904            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18905                ContentProviderConnection conn = app.conProviders.get(i);
18906                conn.provider.connections.remove(conn);
18907                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18908                        conn.provider.name);
18909            }
18910            app.conProviders.clear();
18911        }
18912
18913        // At this point there may be remaining entries in mLaunchingProviders
18914        // where we were the only one waiting, so they are no longer of use.
18915        // Look for these and clean up if found.
18916        // XXX Commented out for now.  Trying to figure out a way to reproduce
18917        // the actual situation to identify what is actually going on.
18918        if (false) {
18919            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18920                ContentProviderRecord cpr = mLaunchingProviders.get(i);
18921                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18922                    synchronized (cpr) {
18923                        cpr.launchingApp = null;
18924                        cpr.notifyAll();
18925                    }
18926                }
18927            }
18928        }
18929
18930        skipCurrentReceiverLocked(app);
18931
18932        // Unregister any receivers.
18933        for (int i = app.receivers.size() - 1; i >= 0; i--) {
18934            removeReceiverLocked(app.receivers.valueAt(i));
18935        }
18936        app.receivers.clear();
18937
18938        // If the app is undergoing backup, tell the backup manager about it
18939        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18940            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18941                    + mBackupTarget.appInfo + " died during backup");
18942            mHandler.post(new Runnable() {
18943                @Override
18944                public void run(){
18945                    try {
18946                        IBackupManager bm = IBackupManager.Stub.asInterface(
18947                                ServiceManager.getService(Context.BACKUP_SERVICE));
18948                        bm.agentDisconnected(app.info.packageName);
18949                    } catch (RemoteException e) {
18950                        // can't happen; backup manager is local
18951                    }
18952                }
18953            });
18954        }
18955
18956        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18957            ProcessChangeItem item = mPendingProcessChanges.get(i);
18958            if (app.pid > 0 && item.pid == app.pid) {
18959                mPendingProcessChanges.remove(i);
18960                mAvailProcessChanges.add(item);
18961            }
18962        }
18963        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18964                null).sendToTarget();
18965
18966        // If the caller is restarting this app, then leave it in its
18967        // current lists and let the caller take care of it.
18968        if (restarting) {
18969            return false;
18970        }
18971
18972        if (!app.persistent || app.isolated) {
18973            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18974                    "Removing non-persistent process during cleanup: " + app);
18975            if (!replacingPid) {
18976                removeProcessNameLocked(app.processName, app.uid, app);
18977            }
18978            if (mHeavyWeightProcess == app) {
18979                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18980                        mHeavyWeightProcess.userId, 0));
18981                mHeavyWeightProcess = null;
18982            }
18983        } else if (!app.removed) {
18984            // This app is persistent, so we need to keep its record around.
18985            // If it is not already on the pending app list, add it there
18986            // and start a new process for it.
18987            if (mPersistentStartingProcesses.indexOf(app) < 0) {
18988                mPersistentStartingProcesses.add(app);
18989                restart = true;
18990            }
18991        }
18992        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18993                TAG_CLEANUP, "Clean-up removing on hold: " + app);
18994        mProcessesOnHold.remove(app);
18995
18996        if (app == mHomeProcess) {
18997            mHomeProcess = null;
18998        }
18999        if (app == mPreviousProcess) {
19000            mPreviousProcess = null;
19001        }
19002
19003        if (restart && !app.isolated) {
19004            // We have components that still need to be running in the
19005            // process, so re-launch it.
19006            if (index < 0) {
19007                ProcessList.remove(app.pid);
19008            }
19009            addProcessNameLocked(app);
19010            app.pendingStart = false;
19011            startProcessLocked(app, "restart", app.processName);
19012            return true;
19013        } else if (app.pid > 0 && app.pid != MY_PID) {
19014            // Goodbye!
19015            boolean removed;
19016            synchronized (mPidsSelfLocked) {
19017                mPidsSelfLocked.remove(app.pid);
19018                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
19019            }
19020            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
19021            if (app.isolated) {
19022                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
19023            }
19024            app.setPid(0);
19025        }
19026        return false;
19027    }
19028
19029    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
19030        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19031            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19032            if (cpr.launchingApp == app) {
19033                return true;
19034            }
19035        }
19036        return false;
19037    }
19038
19039    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
19040        // Look through the content providers we are waiting to have launched,
19041        // and if any run in this process then either schedule a restart of
19042        // the process or kill the client waiting for it if this process has
19043        // gone bad.
19044        boolean restart = false;
19045        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19046            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19047            if (cpr.launchingApp == app) {
19048                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
19049                    restart = true;
19050                } else {
19051                    removeDyingProviderLocked(app, cpr, true);
19052                }
19053            }
19054        }
19055        return restart;
19056    }
19057
19058    // =========================================================
19059    // SERVICES
19060    // =========================================================
19061
19062    @Override
19063    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
19064        enforceNotIsolatedCaller("getServices");
19065
19066        final int callingUid = Binder.getCallingUid();
19067        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
19068            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
19069        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
19070            callingUid);
19071        synchronized (this) {
19072            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
19073                allowed, canInteractAcrossUsers);
19074        }
19075    }
19076
19077    @Override
19078    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
19079        enforceNotIsolatedCaller("getRunningServiceControlPanel");
19080        synchronized (this) {
19081            return mServices.getRunningServiceControlPanelLocked(name);
19082        }
19083    }
19084
19085    @Override
19086    public ComponentName startService(IApplicationThread caller, Intent service,
19087            String resolvedType, boolean requireForeground, String callingPackage, int userId)
19088            throws TransactionTooLargeException {
19089        enforceNotIsolatedCaller("startService");
19090        // Refuse possible leaked file descriptors
19091        if (service != null && service.hasFileDescriptors() == true) {
19092            throw new IllegalArgumentException("File descriptors passed in Intent");
19093        }
19094
19095        if (callingPackage == null) {
19096            throw new IllegalArgumentException("callingPackage cannot be null");
19097        }
19098
19099        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
19100                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
19101        synchronized(this) {
19102            final int callingPid = Binder.getCallingPid();
19103            final int callingUid = Binder.getCallingUid();
19104            final long origId = Binder.clearCallingIdentity();
19105            ComponentName res;
19106            try {
19107                res = mServices.startServiceLocked(caller, service,
19108                        resolvedType, callingPid, callingUid,
19109                        requireForeground, callingPackage, userId);
19110            } finally {
19111                Binder.restoreCallingIdentity(origId);
19112            }
19113            return res;
19114        }
19115    }
19116
19117    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
19118            boolean fgRequired, String callingPackage, int userId)
19119            throws TransactionTooLargeException {
19120        synchronized(this) {
19121            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
19122                    "startServiceInPackage: " + service + " type=" + resolvedType);
19123            final long origId = Binder.clearCallingIdentity();
19124            ComponentName res;
19125            try {
19126                res = mServices.startServiceLocked(null, service,
19127                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
19128            } finally {
19129                Binder.restoreCallingIdentity(origId);
19130            }
19131            return res;
19132        }
19133    }
19134
19135    @Override
19136    public int stopService(IApplicationThread caller, Intent service,
19137            String resolvedType, int userId) {
19138        enforceNotIsolatedCaller("stopService");
19139        // Refuse possible leaked file descriptors
19140        if (service != null && service.hasFileDescriptors() == true) {
19141            throw new IllegalArgumentException("File descriptors passed in Intent");
19142        }
19143
19144        synchronized(this) {
19145            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
19146        }
19147    }
19148
19149    @Override
19150    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
19151        enforceNotIsolatedCaller("peekService");
19152        // Refuse possible leaked file descriptors
19153        if (service != null && service.hasFileDescriptors() == true) {
19154            throw new IllegalArgumentException("File descriptors passed in Intent");
19155        }
19156
19157        if (callingPackage == null) {
19158            throw new IllegalArgumentException("callingPackage cannot be null");
19159        }
19160
19161        synchronized(this) {
19162            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
19163        }
19164    }
19165
19166    @Override
19167    public boolean stopServiceToken(ComponentName className, IBinder token,
19168            int startId) {
19169        synchronized(this) {
19170            return mServices.stopServiceTokenLocked(className, token, startId);
19171        }
19172    }
19173
19174    @Override
19175    public void setServiceForeground(ComponentName className, IBinder token,
19176            int id, Notification notification, int flags) {
19177        synchronized(this) {
19178            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
19179        }
19180    }
19181
19182    @Override
19183    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
19184            boolean requireFull, String name, String callerPackage) {
19185        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
19186                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
19187    }
19188
19189    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
19190            String className, int flags) {
19191        boolean result = false;
19192        // For apps that don't have pre-defined UIDs, check for permission
19193        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
19194            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
19195                if (ActivityManager.checkUidPermission(
19196                        INTERACT_ACROSS_USERS,
19197                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
19198                    ComponentName comp = new ComponentName(aInfo.packageName, className);
19199                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
19200                            + " requests FLAG_SINGLE_USER, but app does not hold "
19201                            + INTERACT_ACROSS_USERS;
19202                    Slog.w(TAG, msg);
19203                    throw new SecurityException(msg);
19204                }
19205                // Permission passed
19206                result = true;
19207            }
19208        } else if ("system".equals(componentProcessName)) {
19209            result = true;
19210        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
19211            // Phone app and persistent apps are allowed to export singleuser providers.
19212            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
19213                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
19214        }
19215        if (DEBUG_MU) Slog.v(TAG_MU,
19216                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
19217                + Integer.toHexString(flags) + ") = " + result);
19218        return result;
19219    }
19220
19221    /**
19222     * Checks to see if the caller is in the same app as the singleton
19223     * component, or the component is in a special app. It allows special apps
19224     * to export singleton components but prevents exporting singleton
19225     * components for regular apps.
19226     */
19227    boolean isValidSingletonCall(int callingUid, int componentUid) {
19228        int componentAppId = UserHandle.getAppId(componentUid);
19229        return UserHandle.isSameApp(callingUid, componentUid)
19230                || componentAppId == SYSTEM_UID
19231                || componentAppId == PHONE_UID
19232                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
19233                        == PackageManager.PERMISSION_GRANTED;
19234    }
19235
19236    public int bindService(IApplicationThread caller, IBinder token, Intent service,
19237            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
19238            int userId) throws TransactionTooLargeException {
19239        enforceNotIsolatedCaller("bindService");
19240
19241        // Refuse possible leaked file descriptors
19242        if (service != null && service.hasFileDescriptors() == true) {
19243            throw new IllegalArgumentException("File descriptors passed in Intent");
19244        }
19245
19246        if (callingPackage == null) {
19247            throw new IllegalArgumentException("callingPackage cannot be null");
19248        }
19249
19250        synchronized(this) {
19251            return mServices.bindServiceLocked(caller, token, service,
19252                    resolvedType, connection, flags, callingPackage, userId);
19253        }
19254    }
19255
19256    public boolean unbindService(IServiceConnection connection) {
19257        synchronized (this) {
19258            return mServices.unbindServiceLocked(connection);
19259        }
19260    }
19261
19262    public void publishService(IBinder token, Intent intent, IBinder service) {
19263        // Refuse possible leaked file descriptors
19264        if (intent != null && intent.hasFileDescriptors() == true) {
19265            throw new IllegalArgumentException("File descriptors passed in Intent");
19266        }
19267
19268        synchronized(this) {
19269            if (!(token instanceof ServiceRecord)) {
19270                throw new IllegalArgumentException("Invalid service token");
19271            }
19272            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
19273        }
19274    }
19275
19276    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
19277        // Refuse possible leaked file descriptors
19278        if (intent != null && intent.hasFileDescriptors() == true) {
19279            throw new IllegalArgumentException("File descriptors passed in Intent");
19280        }
19281
19282        synchronized(this) {
19283            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
19284        }
19285    }
19286
19287    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
19288        synchronized(this) {
19289            if (!(token instanceof ServiceRecord)) {
19290                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
19291                throw new IllegalArgumentException("Invalid service token");
19292            }
19293            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
19294        }
19295    }
19296
19297    // =========================================================
19298    // BACKUP AND RESTORE
19299    // =========================================================
19300
19301    // Cause the target app to be launched if necessary and its backup agent
19302    // instantiated.  The backup agent will invoke backupAgentCreated() on the
19303    // activity manager to announce its creation.
19304    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
19305        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
19306        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
19307
19308        IPackageManager pm = AppGlobals.getPackageManager();
19309        ApplicationInfo app = null;
19310        try {
19311            app = pm.getApplicationInfo(packageName, 0, userId);
19312        } catch (RemoteException e) {
19313            // can't happen; package manager is process-local
19314        }
19315        if (app == null) {
19316            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
19317            return false;
19318        }
19319
19320        int oldBackupUid;
19321        int newBackupUid;
19322
19323        synchronized(this) {
19324            // !!! TODO: currently no check here that we're already bound
19325            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
19326            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19327            synchronized (stats) {
19328                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
19329            }
19330
19331            // Backup agent is now in use, its package can't be stopped.
19332            try {
19333                AppGlobals.getPackageManager().setPackageStoppedState(
19334                        app.packageName, false, UserHandle.getUserId(app.uid));
19335            } catch (RemoteException e) {
19336            } catch (IllegalArgumentException e) {
19337                Slog.w(TAG, "Failed trying to unstop package "
19338                        + app.packageName + ": " + e);
19339            }
19340
19341            BackupRecord r = new BackupRecord(ss, app, backupMode);
19342            ComponentName hostingName =
19343                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
19344                            ? new ComponentName(app.packageName, app.backupAgentName)
19345                            : new ComponentName("android", "FullBackupAgent");
19346            // startProcessLocked() returns existing proc's record if it's already running
19347            ProcessRecord proc = startProcessLocked(app.processName, app,
19348                    false, 0, "backup", hostingName, false, false, false);
19349            if (proc == null) {
19350                Slog.e(TAG, "Unable to start backup agent process " + r);
19351                return false;
19352            }
19353
19354            // If the app is a regular app (uid >= 10000) and not the system server or phone
19355            // process, etc, then mark it as being in full backup so that certain calls to the
19356            // process can be blocked. This is not reset to false anywhere because we kill the
19357            // process after the full backup is done and the ProcessRecord will vaporize anyway.
19358            if (UserHandle.isApp(app.uid) &&
19359                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
19360                proc.inFullBackup = true;
19361            }
19362            r.app = proc;
19363            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
19364            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
19365            mBackupTarget = r;
19366            mBackupAppName = app.packageName;
19367
19368            // Try not to kill the process during backup
19369            updateOomAdjLocked(proc, true);
19370
19371            // If the process is already attached, schedule the creation of the backup agent now.
19372            // If it is not yet live, this will be done when it attaches to the framework.
19373            if (proc.thread != null) {
19374                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
19375                try {
19376                    proc.thread.scheduleCreateBackupAgent(app,
19377                            compatibilityInfoForPackageLocked(app), backupMode);
19378                } catch (RemoteException e) {
19379                    // Will time out on the backup manager side
19380                }
19381            } else {
19382                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
19383            }
19384            // Invariants: at this point, the target app process exists and the application
19385            // is either already running or in the process of coming up.  mBackupTarget and
19386            // mBackupAppName describe the app, so that when it binds back to the AM we
19387            // know that it's scheduled for a backup-agent operation.
19388        }
19389
19390        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
19391        if (oldBackupUid != -1) {
19392            js.removeBackingUpUid(oldBackupUid);
19393        }
19394        if (newBackupUid != -1) {
19395            js.addBackingUpUid(newBackupUid);
19396        }
19397
19398        return true;
19399    }
19400
19401    @Override
19402    public void clearPendingBackup() {
19403        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
19404        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
19405
19406        synchronized (this) {
19407            mBackupTarget = null;
19408            mBackupAppName = null;
19409        }
19410
19411        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
19412        js.clearAllBackingUpUids();
19413    }
19414
19415    // A backup agent has just come up
19416    public void backupAgentCreated(String agentPackageName, IBinder agent) {
19417        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
19418                + " = " + agent);
19419
19420        synchronized(this) {
19421            if (!agentPackageName.equals(mBackupAppName)) {
19422                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
19423                return;
19424            }
19425        }
19426
19427        long oldIdent = Binder.clearCallingIdentity();
19428        try {
19429            IBackupManager bm = IBackupManager.Stub.asInterface(
19430                    ServiceManager.getService(Context.BACKUP_SERVICE));
19431            bm.agentConnected(agentPackageName, agent);
19432        } catch (RemoteException e) {
19433            // can't happen; the backup manager service is local
19434        } catch (Exception e) {
19435            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
19436            e.printStackTrace();
19437        } finally {
19438            Binder.restoreCallingIdentity(oldIdent);
19439        }
19440    }
19441
19442    // done with this agent
19443    public void unbindBackupAgent(ApplicationInfo appInfo) {
19444        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
19445        if (appInfo == null) {
19446            Slog.w(TAG, "unbind backup agent for null app");
19447            return;
19448        }
19449
19450        int oldBackupUid;
19451
19452        synchronized(this) {
19453            try {
19454                if (mBackupAppName == null) {
19455                    Slog.w(TAG, "Unbinding backup agent with no active backup");
19456                    return;
19457                }
19458
19459                if (!mBackupAppName.equals(appInfo.packageName)) {
19460                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
19461                    return;
19462                }
19463
19464                // Not backing this app up any more; reset its OOM adjustment
19465                final ProcessRecord proc = mBackupTarget.app;
19466                updateOomAdjLocked(proc, true);
19467                proc.inFullBackup = false;
19468
19469                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
19470
19471                // If the app crashed during backup, 'thread' will be null here
19472                if (proc.thread != null) {
19473                    try {
19474                        proc.thread.scheduleDestroyBackupAgent(appInfo,
19475                                compatibilityInfoForPackageLocked(appInfo));
19476                    } catch (Exception e) {
19477                        Slog.e(TAG, "Exception when unbinding backup agent:");
19478                        e.printStackTrace();
19479                    }
19480                }
19481            } finally {
19482                mBackupTarget = null;
19483                mBackupAppName = null;
19484            }
19485        }
19486
19487        if (oldBackupUid != -1) {
19488            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
19489            js.removeBackingUpUid(oldBackupUid);
19490        }
19491    }
19492
19493    // =========================================================
19494    // BROADCASTS
19495    // =========================================================
19496
19497    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
19498        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
19499            return false;
19500        }
19501        // Easy case -- we have the app's ProcessRecord.
19502        if (record != null) {
19503            return record.info.isInstantApp();
19504        }
19505        // Otherwise check with PackageManager.
19506        if (callerPackage == null) {
19507            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
19508            throw new IllegalArgumentException("Calling application did not provide package name");
19509        }
19510        mAppOpsService.checkPackage(uid, callerPackage);
19511        try {
19512            IPackageManager pm = AppGlobals.getPackageManager();
19513            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
19514        } catch (RemoteException e) {
19515            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
19516            return true;
19517        }
19518    }
19519
19520    boolean isPendingBroadcastProcessLocked(int pid) {
19521        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
19522                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
19523    }
19524
19525    void skipPendingBroadcastLocked(int pid) {
19526            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
19527            for (BroadcastQueue queue : mBroadcastQueues) {
19528                queue.skipPendingBroadcastLocked(pid);
19529            }
19530    }
19531
19532    // The app just attached; send any pending broadcasts that it should receive
19533    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
19534        boolean didSomething = false;
19535        for (BroadcastQueue queue : mBroadcastQueues) {
19536            didSomething |= queue.sendPendingBroadcastsLocked(app);
19537        }
19538        return didSomething;
19539    }
19540
19541    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
19542            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
19543            int flags) {
19544        enforceNotIsolatedCaller("registerReceiver");
19545        ArrayList<Intent> stickyIntents = null;
19546        ProcessRecord callerApp = null;
19547        final boolean visibleToInstantApps
19548                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
19549        int callingUid;
19550        int callingPid;
19551        boolean instantApp;
19552        synchronized(this) {
19553            if (caller != null) {
19554                callerApp = getRecordForAppLocked(caller);
19555                if (callerApp == null) {
19556                    throw new SecurityException(
19557                            "Unable to find app for caller " + caller
19558                            + " (pid=" + Binder.getCallingPid()
19559                            + ") when registering receiver " + receiver);
19560                }
19561                if (callerApp.info.uid != SYSTEM_UID &&
19562                        !callerApp.pkgList.containsKey(callerPackage) &&
19563                        !"android".equals(callerPackage)) {
19564                    throw new SecurityException("Given caller package " + callerPackage
19565                            + " is not running in process " + callerApp);
19566                }
19567                callingUid = callerApp.info.uid;
19568                callingPid = callerApp.pid;
19569            } else {
19570                callerPackage = null;
19571                callingUid = Binder.getCallingUid();
19572                callingPid = Binder.getCallingPid();
19573            }
19574
19575            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
19576            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19577                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
19578
19579            Iterator<String> actions = filter.actionsIterator();
19580            if (actions == null) {
19581                ArrayList<String> noAction = new ArrayList<String>(1);
19582                noAction.add(null);
19583                actions = noAction.iterator();
19584            }
19585
19586            // Collect stickies of users
19587            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
19588            while (actions.hasNext()) {
19589                String action = actions.next();
19590                for (int id : userIds) {
19591                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
19592                    if (stickies != null) {
19593                        ArrayList<Intent> intents = stickies.get(action);
19594                        if (intents != null) {
19595                            if (stickyIntents == null) {
19596                                stickyIntents = new ArrayList<Intent>();
19597                            }
19598                            stickyIntents.addAll(intents);
19599                        }
19600                    }
19601                }
19602            }
19603        }
19604
19605        ArrayList<Intent> allSticky = null;
19606        if (stickyIntents != null) {
19607            final ContentResolver resolver = mContext.getContentResolver();
19608            // Look for any matching sticky broadcasts...
19609            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
19610                Intent intent = stickyIntents.get(i);
19611                // Don't provided intents that aren't available to instant apps.
19612                if (instantApp &&
19613                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
19614                    continue;
19615                }
19616                // If intent has scheme "content", it will need to acccess
19617                // provider that needs to lock mProviderMap in ActivityThread
19618                // and also it may need to wait application response, so we
19619                // cannot lock ActivityManagerService here.
19620                if (filter.match(resolver, intent, true, TAG) >= 0) {
19621                    if (allSticky == null) {
19622                        allSticky = new ArrayList<Intent>();
19623                    }
19624                    allSticky.add(intent);
19625                }
19626            }
19627        }
19628
19629        // The first sticky in the list is returned directly back to the client.
19630        Intent sticky = allSticky != null ? allSticky.get(0) : null;
19631        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
19632        if (receiver == null) {
19633            return sticky;
19634        }
19635
19636        synchronized (this) {
19637            if (callerApp != null && (callerApp.thread == null
19638                    || callerApp.thread.asBinder() != caller.asBinder())) {
19639                // Original caller already died
19640                return null;
19641            }
19642            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
19643            if (rl == null) {
19644                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
19645                        userId, receiver);
19646                if (rl.app != null) {
19647                    rl.app.receivers.add(rl);
19648                } else {
19649                    try {
19650                        receiver.asBinder().linkToDeath(rl, 0);
19651                    } catch (RemoteException e) {
19652                        return sticky;
19653                    }
19654                    rl.linkedToDeath = true;
19655                }
19656                mRegisteredReceivers.put(receiver.asBinder(), rl);
19657            } else if (rl.uid != callingUid) {
19658                throw new IllegalArgumentException(
19659                        "Receiver requested to register for uid " + callingUid
19660                        + " was previously registered for uid " + rl.uid
19661                        + " callerPackage is " + callerPackage);
19662            } else if (rl.pid != callingPid) {
19663                throw new IllegalArgumentException(
19664                        "Receiver requested to register for pid " + callingPid
19665                        + " was previously registered for pid " + rl.pid
19666                        + " callerPackage is " + callerPackage);
19667            } else if (rl.userId != userId) {
19668                throw new IllegalArgumentException(
19669                        "Receiver requested to register for user " + userId
19670                        + " was previously registered for user " + rl.userId
19671                        + " callerPackage is " + callerPackage);
19672            }
19673            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
19674                    permission, callingUid, userId, instantApp, visibleToInstantApps);
19675            rl.add(bf);
19676            if (!bf.debugCheck()) {
19677                Slog.w(TAG, "==> For Dynamic broadcast");
19678            }
19679            mReceiverResolver.addFilter(bf);
19680
19681            // Enqueue broadcasts for all existing stickies that match
19682            // this filter.
19683            if (allSticky != null) {
19684                ArrayList receivers = new ArrayList();
19685                receivers.add(bf);
19686
19687                final int stickyCount = allSticky.size();
19688                for (int i = 0; i < stickyCount; i++) {
19689                    Intent intent = allSticky.get(i);
19690                    BroadcastQueue queue = broadcastQueueForIntent(intent);
19691                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
19692                            null, -1, -1, false, null, null, OP_NONE, null, receivers,
19693                            null, 0, null, null, false, true, true, -1);
19694                    queue.enqueueParallelBroadcastLocked(r);
19695                    queue.scheduleBroadcastsLocked();
19696                }
19697            }
19698
19699            return sticky;
19700        }
19701    }
19702
19703    public void unregisterReceiver(IIntentReceiver receiver) {
19704        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
19705
19706        final long origId = Binder.clearCallingIdentity();
19707        try {
19708            boolean doTrim = false;
19709
19710            synchronized(this) {
19711                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
19712                if (rl != null) {
19713                    final BroadcastRecord r = rl.curBroadcast;
19714                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
19715                        final boolean doNext = r.queue.finishReceiverLocked(
19716                                r, r.resultCode, r.resultData, r.resultExtras,
19717                                r.resultAbort, false);
19718                        if (doNext) {
19719                            doTrim = true;
19720                            r.queue.processNextBroadcast(false);
19721                        }
19722                    }
19723
19724                    if (rl.app != null) {
19725                        rl.app.receivers.remove(rl);
19726                    }
19727                    removeReceiverLocked(rl);
19728                    if (rl.linkedToDeath) {
19729                        rl.linkedToDeath = false;
19730                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
19731                    }
19732                }
19733            }
19734
19735            // If we actually concluded any broadcasts, we might now be able
19736            // to trim the recipients' apps from our working set
19737            if (doTrim) {
19738                trimApplications();
19739                return;
19740            }
19741
19742        } finally {
19743            Binder.restoreCallingIdentity(origId);
19744        }
19745    }
19746
19747    void removeReceiverLocked(ReceiverList rl) {
19748        mRegisteredReceivers.remove(rl.receiver.asBinder());
19749        for (int i = rl.size() - 1; i >= 0; i--) {
19750            mReceiverResolver.removeFilter(rl.get(i));
19751        }
19752    }
19753
19754    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
19755        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19756            ProcessRecord r = mLruProcesses.get(i);
19757            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
19758                try {
19759                    r.thread.dispatchPackageBroadcast(cmd, packages);
19760                } catch (RemoteException ex) {
19761                }
19762            }
19763        }
19764    }
19765
19766    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
19767            int callingUid, int[] users) {
19768        // TODO: come back and remove this assumption to triage all broadcasts
19769        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
19770
19771        List<ResolveInfo> receivers = null;
19772        try {
19773            HashSet<ComponentName> singleUserReceivers = null;
19774            boolean scannedFirstReceivers = false;
19775            for (int user : users) {
19776                // Skip users that have Shell restrictions, with exception of always permitted
19777                // Shell broadcasts
19778                if (callingUid == SHELL_UID
19779                        && mUserController.hasUserRestriction(
19780                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
19781                        && !isPermittedShellBroadcast(intent)) {
19782                    continue;
19783                }
19784                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
19785                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
19786                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
19787                    // If this is not the system user, we need to check for
19788                    // any receivers that should be filtered out.
19789                    for (int i=0; i<newReceivers.size(); i++) {
19790                        ResolveInfo ri = newReceivers.get(i);
19791                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
19792                            newReceivers.remove(i);
19793                            i--;
19794                        }
19795                    }
19796                }
19797                if (newReceivers != null && newReceivers.size() == 0) {
19798                    newReceivers = null;
19799                }
19800                if (receivers == null) {
19801                    receivers = newReceivers;
19802                } else if (newReceivers != null) {
19803                    // We need to concatenate the additional receivers
19804                    // found with what we have do far.  This would be easy,
19805                    // but we also need to de-dup any receivers that are
19806                    // singleUser.
19807                    if (!scannedFirstReceivers) {
19808                        // Collect any single user receivers we had already retrieved.
19809                        scannedFirstReceivers = true;
19810                        for (int i=0; i<receivers.size(); i++) {
19811                            ResolveInfo ri = receivers.get(i);
19812                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19813                                ComponentName cn = new ComponentName(
19814                                        ri.activityInfo.packageName, ri.activityInfo.name);
19815                                if (singleUserReceivers == null) {
19816                                    singleUserReceivers = new HashSet<ComponentName>();
19817                                }
19818                                singleUserReceivers.add(cn);
19819                            }
19820                        }
19821                    }
19822                    // Add the new results to the existing results, tracking
19823                    // and de-dupping single user receivers.
19824                    for (int i=0; i<newReceivers.size(); i++) {
19825                        ResolveInfo ri = newReceivers.get(i);
19826                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19827                            ComponentName cn = new ComponentName(
19828                                    ri.activityInfo.packageName, ri.activityInfo.name);
19829                            if (singleUserReceivers == null) {
19830                                singleUserReceivers = new HashSet<ComponentName>();
19831                            }
19832                            if (!singleUserReceivers.contains(cn)) {
19833                                singleUserReceivers.add(cn);
19834                                receivers.add(ri);
19835                            }
19836                        } else {
19837                            receivers.add(ri);
19838                        }
19839                    }
19840                }
19841            }
19842        } catch (RemoteException ex) {
19843            // pm is in same process, this will never happen.
19844        }
19845        return receivers;
19846    }
19847
19848    private boolean isPermittedShellBroadcast(Intent intent) {
19849        // remote bugreport should always be allowed to be taken
19850        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19851    }
19852
19853    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19854            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19855        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19856            // Don't yell about broadcasts sent via shell
19857            return;
19858        }
19859
19860        final String action = intent.getAction();
19861        if (isProtectedBroadcast
19862                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19863                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19864                || Intent.ACTION_MEDIA_BUTTON.equals(action)
19865                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19866                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19867                || Intent.ACTION_MASTER_CLEAR.equals(action)
19868                || Intent.ACTION_FACTORY_RESET.equals(action)
19869                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19870                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19871                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19872                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19873                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19874                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19875                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19876            // Broadcast is either protected, or it's a public action that
19877            // we've relaxed, so it's fine for system internals to send.
19878            return;
19879        }
19880
19881        // This broadcast may be a problem...  but there are often system components that
19882        // want to send an internal broadcast to themselves, which is annoying to have to
19883        // explicitly list each action as a protected broadcast, so we will check for that
19884        // one safe case and allow it: an explicit broadcast, only being received by something
19885        // that has protected itself.
19886        if (receivers != null && receivers.size() > 0
19887                && (intent.getPackage() != null || intent.getComponent() != null)) {
19888            boolean allProtected = true;
19889            for (int i = receivers.size()-1; i >= 0; i--) {
19890                Object target = receivers.get(i);
19891                if (target instanceof ResolveInfo) {
19892                    ResolveInfo ri = (ResolveInfo)target;
19893                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19894                        allProtected = false;
19895                        break;
19896                    }
19897                } else {
19898                    BroadcastFilter bf = (BroadcastFilter)target;
19899                    if (bf.requiredPermission == null) {
19900                        allProtected = false;
19901                        break;
19902                    }
19903                }
19904            }
19905            if (allProtected) {
19906                // All safe!
19907                return;
19908            }
19909        }
19910
19911        // The vast majority of broadcasts sent from system internals
19912        // should be protected to avoid security holes, so yell loudly
19913        // to ensure we examine these cases.
19914        if (callerApp != null) {
19915            Log.wtf(TAG, "Sending non-protected broadcast " + action
19916                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19917                    new Throwable());
19918        } else {
19919            Log.wtf(TAG, "Sending non-protected broadcast " + action
19920                            + " from system uid " + UserHandle.formatUid(callingUid)
19921                            + " pkg " + callerPackage,
19922                    new Throwable());
19923        }
19924    }
19925
19926    final int broadcastIntentLocked(ProcessRecord callerApp,
19927            String callerPackage, Intent intent, String resolvedType,
19928            IIntentReceiver resultTo, int resultCode, String resultData,
19929            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19930            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19931        intent = new Intent(intent);
19932
19933        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19934        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19935        if (callerInstantApp) {
19936            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19937        }
19938
19939        // By default broadcasts do not go to stopped apps.
19940        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19941
19942        // If we have not finished booting, don't allow this to launch new processes.
19943        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19944            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19945        }
19946
19947        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19948                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19949                + " ordered=" + ordered + " userid=" + userId);
19950        if ((resultTo != null) && !ordered) {
19951            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19952        }
19953
19954        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19955                ALLOW_NON_FULL, "broadcast", callerPackage);
19956
19957        // Make sure that the user who is receiving this broadcast or its parent is running.
19958        // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
19959        if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
19960            if ((callingUid != SYSTEM_UID
19961                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19962                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19963                Slog.w(TAG, "Skipping broadcast of " + intent
19964                        + ": user " + userId + " and its parent (if any) are stopped");
19965                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19966            }
19967        }
19968
19969        BroadcastOptions brOptions = null;
19970        if (bOptions != null) {
19971            brOptions = new BroadcastOptions(bOptions);
19972            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19973                // See if the caller is allowed to do this.  Note we are checking against
19974                // the actual real caller (not whoever provided the operation as say a
19975                // PendingIntent), because that who is actually supplied the arguments.
19976                if (checkComponentPermission(
19977                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19978                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19979                        != PackageManager.PERMISSION_GRANTED) {
19980                    String msg = "Permission Denial: " + intent.getAction()
19981                            + " broadcast from " + callerPackage + " (pid=" + callingPid
19982                            + ", uid=" + callingUid + ")"
19983                            + " requires "
19984                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19985                    Slog.w(TAG, msg);
19986                    throw new SecurityException(msg);
19987                }
19988            }
19989        }
19990
19991        // Verify that protected broadcasts are only being sent by system code,
19992        // and that system code is only sending protected broadcasts.
19993        final String action = intent.getAction();
19994        final boolean isProtectedBroadcast;
19995        try {
19996            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19997        } catch (RemoteException e) {
19998            Slog.w(TAG, "Remote exception", e);
19999            return ActivityManager.BROADCAST_SUCCESS;
20000        }
20001
20002        final boolean isCallerSystem;
20003        switch (UserHandle.getAppId(callingUid)) {
20004            case ROOT_UID:
20005            case SYSTEM_UID:
20006            case PHONE_UID:
20007            case BLUETOOTH_UID:
20008            case NFC_UID:
20009                isCallerSystem = true;
20010                break;
20011            default:
20012                isCallerSystem = (callerApp != null) && callerApp.persistent;
20013                break;
20014        }
20015
20016        // First line security check before anything else: stop non-system apps from
20017        // sending protected broadcasts.
20018        if (!isCallerSystem) {
20019            if (isProtectedBroadcast) {
20020                String msg = "Permission Denial: not allowed to send broadcast "
20021                        + action + " from pid="
20022                        + callingPid + ", uid=" + callingUid;
20023                Slog.w(TAG, msg);
20024                throw new SecurityException(msg);
20025
20026            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
20027                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
20028                // Special case for compatibility: we don't want apps to send this,
20029                // but historically it has not been protected and apps may be using it
20030                // to poke their own app widget.  So, instead of making it protected,
20031                // just limit it to the caller.
20032                if (callerPackage == null) {
20033                    String msg = "Permission Denial: not allowed to send broadcast "
20034                            + action + " from unknown caller.";
20035                    Slog.w(TAG, msg);
20036                    throw new SecurityException(msg);
20037                } else if (intent.getComponent() != null) {
20038                    // They are good enough to send to an explicit component...  verify
20039                    // it is being sent to the calling app.
20040                    if (!intent.getComponent().getPackageName().equals(
20041                            callerPackage)) {
20042                        String msg = "Permission Denial: not allowed to send broadcast "
20043                                + action + " to "
20044                                + intent.getComponent().getPackageName() + " from "
20045                                + callerPackage;
20046                        Slog.w(TAG, msg);
20047                        throw new SecurityException(msg);
20048                    }
20049                } else {
20050                    // Limit broadcast to their own package.
20051                    intent.setPackage(callerPackage);
20052                }
20053            }
20054        }
20055
20056        if (action != null) {
20057            if (getBackgroundLaunchBroadcasts().contains(action)) {
20058                if (DEBUG_BACKGROUND_CHECK) {
20059                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
20060                }
20061                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
20062            }
20063
20064            switch (action) {
20065                case Intent.ACTION_UID_REMOVED:
20066                case Intent.ACTION_PACKAGE_REMOVED:
20067                case Intent.ACTION_PACKAGE_CHANGED:
20068                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
20069                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
20070                case Intent.ACTION_PACKAGES_SUSPENDED:
20071                case Intent.ACTION_PACKAGES_UNSUSPENDED:
20072                    // Handle special intents: if this broadcast is from the package
20073                    // manager about a package being removed, we need to remove all of
20074                    // its activities from the history stack.
20075                    if (checkComponentPermission(
20076                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
20077                            callingPid, callingUid, -1, true)
20078                            != PackageManager.PERMISSION_GRANTED) {
20079                        String msg = "Permission Denial: " + intent.getAction()
20080                                + " broadcast from " + callerPackage + " (pid=" + callingPid
20081                                + ", uid=" + callingUid + ")"
20082                                + " requires "
20083                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
20084                        Slog.w(TAG, msg);
20085                        throw new SecurityException(msg);
20086                    }
20087                    switch (action) {
20088                        case Intent.ACTION_UID_REMOVED:
20089                            final int uid = getUidFromIntent(intent);
20090                            if (uid >= 0) {
20091                                mBatteryStatsService.removeUid(uid);
20092                                mAppOpsService.uidRemoved(uid);
20093                            }
20094                            break;
20095                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
20096                            // If resources are unavailable just force stop all those packages
20097                            // and flush the attribute cache as well.
20098                            String list[] =
20099                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
20100                            if (list != null && list.length > 0) {
20101                                for (int i = 0; i < list.length; i++) {
20102                                    forceStopPackageLocked(list[i], -1, false, true, true,
20103                                            false, false, userId, "storage unmount");
20104                                }
20105                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
20106                                sendPackageBroadcastLocked(
20107                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
20108                                        list, userId);
20109                            }
20110                            break;
20111                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
20112                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
20113                            break;
20114                        case Intent.ACTION_PACKAGE_REMOVED:
20115                        case Intent.ACTION_PACKAGE_CHANGED:
20116                            Uri data = intent.getData();
20117                            String ssp;
20118                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
20119                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
20120                                final boolean replacing =
20121                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
20122                                final boolean killProcess =
20123                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
20124                                final boolean fullUninstall = removed && !replacing;
20125                                if (removed) {
20126                                    if (killProcess) {
20127                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
20128                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
20129                                                false, true, true, false, fullUninstall, userId,
20130                                                removed ? "pkg removed" : "pkg changed");
20131                                    }
20132                                    final int cmd = killProcess
20133                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
20134                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
20135                                    sendPackageBroadcastLocked(cmd,
20136                                            new String[] {ssp}, userId);
20137                                    if (fullUninstall) {
20138                                        mAppOpsService.packageRemoved(
20139                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
20140
20141                                        // Remove all permissions granted from/to this package
20142                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
20143
20144                                        mRecentTasks.removeTasksByPackageName(ssp, userId);
20145
20146                                        mServices.forceStopPackageLocked(ssp, userId);
20147                                        mAppWarnings.onPackageUninstalled(ssp);
20148                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
20149                                        mBatteryStatsService.notePackageUninstalled(ssp);
20150                                    }
20151                                } else {
20152                                    if (killProcess) {
20153                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
20154                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
20155                                                userId, ProcessList.INVALID_ADJ,
20156                                                false, true, true, false, "change " + ssp);
20157                                    }
20158                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
20159                                            intent.getStringArrayExtra(
20160                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
20161                                }
20162                            }
20163                            break;
20164                        case Intent.ACTION_PACKAGES_SUSPENDED:
20165                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
20166                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
20167                                    intent.getAction());
20168                            final String[] packageNames = intent.getStringArrayExtra(
20169                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
20170                            final int userHandle = intent.getIntExtra(
20171                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
20172
20173                            synchronized(ActivityManagerService.this) {
20174                                mRecentTasks.onPackagesSuspendedChanged(
20175                                        packageNames, suspended, userHandle);
20176                            }
20177                            break;
20178                    }
20179                    break;
20180                case Intent.ACTION_PACKAGE_REPLACED:
20181                {
20182                    final Uri data = intent.getData();
20183                    final String ssp;
20184                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20185                        ApplicationInfo aInfo = null;
20186                        try {
20187                            aInfo = AppGlobals.getPackageManager()
20188                                    .getApplicationInfo(ssp, 0 /*flags*/, userId);
20189                        } catch (RemoteException ignore) {}
20190                        if (aInfo == null) {
20191                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
20192                                    + " ssp=" + ssp + " data=" + data);
20193                            return ActivityManager.BROADCAST_SUCCESS;
20194                        }
20195                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
20196                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
20197                                new String[] {ssp}, userId);
20198                    }
20199                    break;
20200                }
20201                case Intent.ACTION_PACKAGE_ADDED:
20202                {
20203                    // Special case for adding a package: by default turn on compatibility mode.
20204                    Uri data = intent.getData();
20205                    String ssp;
20206                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20207                        final boolean replacing =
20208                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
20209                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
20210
20211                        try {
20212                            ApplicationInfo ai = AppGlobals.getPackageManager().
20213                                    getApplicationInfo(ssp, 0, 0);
20214                            mBatteryStatsService.notePackageInstalled(ssp,
20215                                    ai != null ? ai.versionCode : 0);
20216                        } catch (RemoteException e) {
20217                        }
20218                    }
20219                    break;
20220                }
20221                case Intent.ACTION_PACKAGE_DATA_CLEARED:
20222                {
20223                    Uri data = intent.getData();
20224                    String ssp;
20225                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
20226                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
20227                        mAppWarnings.onPackageDataCleared(ssp);
20228                    }
20229                    break;
20230                }
20231                case Intent.ACTION_TIMEZONE_CHANGED:
20232                    // If this is the time zone changed action, queue up a message that will reset
20233                    // the timezone of all currently running processes. This message will get
20234                    // queued up before the broadcast happens.
20235                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
20236                    break;
20237                case Intent.ACTION_TIME_CHANGED:
20238                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
20239                    // the tri-state value it may contain and "unknown".
20240                    // For convenience we re-use the Intent extra values.
20241                    final int NO_EXTRA_VALUE_FOUND = -1;
20242                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
20243                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
20244                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
20245                    // Only send a message if the time preference is available.
20246                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
20247                        Message updateTimePreferenceMsg =
20248                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
20249                                        timeFormatPreferenceMsgValue, 0);
20250                        mHandler.sendMessage(updateTimePreferenceMsg);
20251                    }
20252                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20253                    synchronized (stats) {
20254                        stats.noteCurrentTimeChangedLocked();
20255                    }
20256                    break;
20257                case Intent.ACTION_CLEAR_DNS_CACHE:
20258                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
20259                    break;
20260                case Proxy.PROXY_CHANGE_ACTION:
20261                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
20262                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
20263                    break;
20264                case android.hardware.Camera.ACTION_NEW_PICTURE:
20265                case android.hardware.Camera.ACTION_NEW_VIDEO:
20266                    // In N we just turned these off; in O we are turing them back on partly,
20267                    // only for registered receivers.  This will still address the main problem
20268                    // (a spam of apps waking up when a picture is taken putting significant
20269                    // memory pressure on the system at a bad point), while still allowing apps
20270                    // that are already actively running to know about this happening.
20271                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20272                    break;
20273                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
20274                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
20275                    break;
20276                case "com.android.launcher.action.INSTALL_SHORTCUT":
20277                    // As of O, we no longer support this broadcasts, even for pre-O apps.
20278                    // Apps should now be using ShortcutManager.pinRequestShortcut().
20279                    Log.w(TAG, "Broadcast " + action
20280                            + " no longer supported. It will not be delivered.");
20281                    return ActivityManager.BROADCAST_SUCCESS;
20282            }
20283
20284            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
20285                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
20286                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
20287                final int uid = getUidFromIntent(intent);
20288                if (uid != -1) {
20289                    final UidRecord uidRec = mActiveUids.get(uid);
20290                    if (uidRec != null) {
20291                        uidRec.updateHasInternetPermission();
20292                    }
20293                }
20294            }
20295        }
20296
20297        // Add to the sticky list if requested.
20298        if (sticky) {
20299            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
20300                    callingPid, callingUid)
20301                    != PackageManager.PERMISSION_GRANTED) {
20302                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
20303                        + callingPid + ", uid=" + callingUid
20304                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
20305                Slog.w(TAG, msg);
20306                throw new SecurityException(msg);
20307            }
20308            if (requiredPermissions != null && requiredPermissions.length > 0) {
20309                Slog.w(TAG, "Can't broadcast sticky intent " + intent
20310                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
20311                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
20312            }
20313            if (intent.getComponent() != null) {
20314                throw new SecurityException(
20315                        "Sticky broadcasts can't target a specific component");
20316            }
20317            // We use userId directly here, since the "all" target is maintained
20318            // as a separate set of sticky broadcasts.
20319            if (userId != UserHandle.USER_ALL) {
20320                // But first, if this is not a broadcast to all users, then
20321                // make sure it doesn't conflict with an existing broadcast to
20322                // all users.
20323                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
20324                        UserHandle.USER_ALL);
20325                if (stickies != null) {
20326                    ArrayList<Intent> list = stickies.get(intent.getAction());
20327                    if (list != null) {
20328                        int N = list.size();
20329                        int i;
20330                        for (i=0; i<N; i++) {
20331                            if (intent.filterEquals(list.get(i))) {
20332                                throw new IllegalArgumentException(
20333                                        "Sticky broadcast " + intent + " for user "
20334                                        + userId + " conflicts with existing global broadcast");
20335                            }
20336                        }
20337                    }
20338                }
20339            }
20340            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
20341            if (stickies == null) {
20342                stickies = new ArrayMap<>();
20343                mStickyBroadcasts.put(userId, stickies);
20344            }
20345            ArrayList<Intent> list = stickies.get(intent.getAction());
20346            if (list == null) {
20347                list = new ArrayList<>();
20348                stickies.put(intent.getAction(), list);
20349            }
20350            final int stickiesCount = list.size();
20351            int i;
20352            for (i = 0; i < stickiesCount; i++) {
20353                if (intent.filterEquals(list.get(i))) {
20354                    // This sticky already exists, replace it.
20355                    list.set(i, new Intent(intent));
20356                    break;
20357                }
20358            }
20359            if (i >= stickiesCount) {
20360                list.add(new Intent(intent));
20361            }
20362        }
20363
20364        int[] users;
20365        if (userId == UserHandle.USER_ALL) {
20366            // Caller wants broadcast to go to all started users.
20367            users = mUserController.getStartedUserArray();
20368        } else {
20369            // Caller wants broadcast to go to one specific user.
20370            users = new int[] {userId};
20371        }
20372
20373        // Figure out who all will receive this broadcast.
20374        List receivers = null;
20375        List<BroadcastFilter> registeredReceivers = null;
20376        // Need to resolve the intent to interested receivers...
20377        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
20378                 == 0) {
20379            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
20380        }
20381        if (intent.getComponent() == null) {
20382            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
20383                // Query one target user at a time, excluding shell-restricted users
20384                for (int i = 0; i < users.length; i++) {
20385                    if (mUserController.hasUserRestriction(
20386                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
20387                        continue;
20388                    }
20389                    List<BroadcastFilter> registeredReceiversForUser =
20390                            mReceiverResolver.queryIntent(intent,
20391                                    resolvedType, false /*defaultOnly*/, users[i]);
20392                    if (registeredReceivers == null) {
20393                        registeredReceivers = registeredReceiversForUser;
20394                    } else if (registeredReceiversForUser != null) {
20395                        registeredReceivers.addAll(registeredReceiversForUser);
20396                    }
20397                }
20398            } else {
20399                registeredReceivers = mReceiverResolver.queryIntent(intent,
20400                        resolvedType, false /*defaultOnly*/, userId);
20401            }
20402        }
20403
20404        final boolean replacePending =
20405                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
20406
20407        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
20408                + " replacePending=" + replacePending);
20409
20410        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
20411        if (!ordered && NR > 0) {
20412            // If we are not serializing this broadcast, then send the
20413            // registered receivers separately so they don't wait for the
20414            // components to be launched.
20415            if (isCallerSystem) {
20416                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
20417                        isProtectedBroadcast, registeredReceivers);
20418            }
20419            final BroadcastQueue queue = broadcastQueueForIntent(intent);
20420            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
20421                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
20422                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
20423                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
20424            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
20425            final boolean replaced = replacePending
20426                    && (queue.replaceParallelBroadcastLocked(r) != null);
20427            // Note: We assume resultTo is null for non-ordered broadcasts.
20428            if (!replaced) {
20429                queue.enqueueParallelBroadcastLocked(r);
20430                queue.scheduleBroadcastsLocked();
20431            }
20432            registeredReceivers = null;
20433            NR = 0;
20434        }
20435
20436        // Merge into one list.
20437        int ir = 0;
20438        if (receivers != null) {
20439            // A special case for PACKAGE_ADDED: do not allow the package
20440            // being added to see this broadcast.  This prevents them from
20441            // using this as a back door to get run as soon as they are
20442            // installed.  Maybe in the future we want to have a special install
20443            // broadcast or such for apps, but we'd like to deliberately make
20444            // this decision.
20445            String skipPackages[] = null;
20446            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
20447                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
20448                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
20449                Uri data = intent.getData();
20450                if (data != null) {
20451                    String pkgName = data.getSchemeSpecificPart();
20452                    if (pkgName != null) {
20453                        skipPackages = new String[] { pkgName };
20454                    }
20455                }
20456            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
20457                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
20458            }
20459            if (skipPackages != null && (skipPackages.length > 0)) {
20460                for (String skipPackage : skipPackages) {
20461                    if (skipPackage != null) {
20462                        int NT = receivers.size();
20463                        for (int it=0; it<NT; it++) {
20464                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
20465                            if (curt.activityInfo.packageName.equals(skipPackage)) {
20466                                receivers.remove(it);
20467                                it--;
20468                                NT--;
20469                            }
20470                        }
20471                    }
20472                }
20473            }
20474
20475            int NT = receivers != null ? receivers.size() : 0;
20476            int it = 0;
20477            ResolveInfo curt = null;
20478            BroadcastFilter curr = null;
20479            while (it < NT && ir < NR) {
20480                if (curt == null) {
20481                    curt = (ResolveInfo)receivers.get(it);
20482                }
20483                if (curr == null) {
20484                    curr = registeredReceivers.get(ir);
20485                }
20486                if (curr.getPriority() >= curt.priority) {
20487                    // Insert this broadcast record into the final list.
20488                    receivers.add(it, curr);
20489                    ir++;
20490                    curr = null;
20491                    it++;
20492                    NT++;
20493                } else {
20494                    // Skip to the next ResolveInfo in the final list.
20495                    it++;
20496                    curt = null;
20497                }
20498            }
20499        }
20500        while (ir < NR) {
20501            if (receivers == null) {
20502                receivers = new ArrayList();
20503            }
20504            receivers.add(registeredReceivers.get(ir));
20505            ir++;
20506        }
20507
20508        if (isCallerSystem) {
20509            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
20510                    isProtectedBroadcast, receivers);
20511        }
20512
20513        if ((receivers != null && receivers.size() > 0)
20514                || resultTo != null) {
20515            BroadcastQueue queue = broadcastQueueForIntent(intent);
20516            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
20517                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
20518                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
20519                    resultData, resultExtras, ordered, sticky, false, userId);
20520
20521            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
20522                    + ": prev had " + queue.mOrderedBroadcasts.size());
20523            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
20524                    "Enqueueing broadcast " + r.intent.getAction());
20525
20526            final BroadcastRecord oldRecord =
20527                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
20528            if (oldRecord != null) {
20529                // Replaced, fire the result-to receiver.
20530                if (oldRecord.resultTo != null) {
20531                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
20532                    try {
20533                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
20534                                oldRecord.intent,
20535                                Activity.RESULT_CANCELED, null, null,
20536                                false, false, oldRecord.userId);
20537                    } catch (RemoteException e) {
20538                        Slog.w(TAG, "Failure ["
20539                                + queue.mQueueName + "] sending broadcast result of "
20540                                + intent, e);
20541
20542                    }
20543                }
20544            } else {
20545                queue.enqueueOrderedBroadcastLocked(r);
20546                queue.scheduleBroadcastsLocked();
20547            }
20548        } else {
20549            // There was nobody interested in the broadcast, but we still want to record
20550            // that it happened.
20551            if (intent.getComponent() == null && intent.getPackage() == null
20552                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
20553                // This was an implicit broadcast... let's record it for posterity.
20554                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
20555            }
20556        }
20557
20558        return ActivityManager.BROADCAST_SUCCESS;
20559    }
20560
20561    /**
20562     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
20563     */
20564    private int getUidFromIntent(Intent intent) {
20565        if (intent == null) {
20566            return -1;
20567        }
20568        final Bundle intentExtras = intent.getExtras();
20569        return intent.hasExtra(Intent.EXTRA_UID)
20570                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
20571    }
20572
20573    final void rotateBroadcastStatsIfNeededLocked() {
20574        final long now = SystemClock.elapsedRealtime();
20575        if (mCurBroadcastStats == null ||
20576                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
20577            mLastBroadcastStats = mCurBroadcastStats;
20578            if (mLastBroadcastStats != null) {
20579                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
20580                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
20581            }
20582            mCurBroadcastStats = new BroadcastStats();
20583        }
20584    }
20585
20586    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
20587            int skipCount, long dispatchTime) {
20588        rotateBroadcastStatsIfNeededLocked();
20589        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
20590    }
20591
20592    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
20593        rotateBroadcastStatsIfNeededLocked();
20594        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
20595    }
20596
20597    final Intent verifyBroadcastLocked(Intent intent) {
20598        // Refuse possible leaked file descriptors
20599        if (intent != null && intent.hasFileDescriptors() == true) {
20600            throw new IllegalArgumentException("File descriptors passed in Intent");
20601        }
20602
20603        int flags = intent.getFlags();
20604
20605        if (!mProcessesReady) {
20606            // if the caller really truly claims to know what they're doing, go
20607            // ahead and allow the broadcast without launching any receivers
20608            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
20609                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
20610            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
20611                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
20612                        + " before boot completion");
20613                throw new IllegalStateException("Cannot broadcast before boot completed");
20614            }
20615        }
20616
20617        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
20618            throw new IllegalArgumentException(
20619                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
20620        }
20621
20622        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
20623            switch (Binder.getCallingUid()) {
20624                case ROOT_UID:
20625                case SHELL_UID:
20626                    break;
20627                default:
20628                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
20629                            + Binder.getCallingUid());
20630                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
20631                    break;
20632            }
20633        }
20634
20635        return intent;
20636    }
20637
20638    public final int broadcastIntent(IApplicationThread caller,
20639            Intent intent, String resolvedType, IIntentReceiver resultTo,
20640            int resultCode, String resultData, Bundle resultExtras,
20641            String[] requiredPermissions, int appOp, Bundle bOptions,
20642            boolean serialized, boolean sticky, int userId) {
20643        enforceNotIsolatedCaller("broadcastIntent");
20644        synchronized(this) {
20645            intent = verifyBroadcastLocked(intent);
20646
20647            final ProcessRecord callerApp = getRecordForAppLocked(caller);
20648            final int callingPid = Binder.getCallingPid();
20649            final int callingUid = Binder.getCallingUid();
20650            final long origId = Binder.clearCallingIdentity();
20651            int res = broadcastIntentLocked(callerApp,
20652                    callerApp != null ? callerApp.info.packageName : null,
20653                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
20654                    requiredPermissions, appOp, bOptions, serialized, sticky,
20655                    callingPid, callingUid, userId);
20656            Binder.restoreCallingIdentity(origId);
20657            return res;
20658        }
20659    }
20660
20661
20662    int broadcastIntentInPackage(String packageName, int uid,
20663            Intent intent, String resolvedType, IIntentReceiver resultTo,
20664            int resultCode, String resultData, Bundle resultExtras,
20665            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
20666            int userId) {
20667        synchronized(this) {
20668            intent = verifyBroadcastLocked(intent);
20669
20670            final long origId = Binder.clearCallingIdentity();
20671            String[] requiredPermissions = requiredPermission == null ? null
20672                    : new String[] {requiredPermission};
20673            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
20674                    resultTo, resultCode, resultData, resultExtras,
20675                    requiredPermissions, OP_NONE, bOptions, serialized,
20676                    sticky, -1, uid, userId);
20677            Binder.restoreCallingIdentity(origId);
20678            return res;
20679        }
20680    }
20681
20682    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
20683        // Refuse possible leaked file descriptors
20684        if (intent != null && intent.hasFileDescriptors() == true) {
20685            throw new IllegalArgumentException("File descriptors passed in Intent");
20686        }
20687
20688        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20689                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
20690
20691        synchronized(this) {
20692            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
20693                    != PackageManager.PERMISSION_GRANTED) {
20694                String msg = "Permission Denial: unbroadcastIntent() from pid="
20695                        + Binder.getCallingPid()
20696                        + ", uid=" + Binder.getCallingUid()
20697                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
20698                Slog.w(TAG, msg);
20699                throw new SecurityException(msg);
20700            }
20701            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
20702            if (stickies != null) {
20703                ArrayList<Intent> list = stickies.get(intent.getAction());
20704                if (list != null) {
20705                    int N = list.size();
20706                    int i;
20707                    for (i=0; i<N; i++) {
20708                        if (intent.filterEquals(list.get(i))) {
20709                            list.remove(i);
20710                            break;
20711                        }
20712                    }
20713                    if (list.size() <= 0) {
20714                        stickies.remove(intent.getAction());
20715                    }
20716                }
20717                if (stickies.size() <= 0) {
20718                    mStickyBroadcasts.remove(userId);
20719                }
20720            }
20721        }
20722    }
20723
20724    void backgroundServicesFinishedLocked(int userId) {
20725        for (BroadcastQueue queue : mBroadcastQueues) {
20726            queue.backgroundServicesFinishedLocked(userId);
20727        }
20728    }
20729
20730    public void finishReceiver(IBinder who, int resultCode, String resultData,
20731            Bundle resultExtras, boolean resultAbort, int flags) {
20732        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
20733
20734        // Refuse possible leaked file descriptors
20735        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
20736            throw new IllegalArgumentException("File descriptors passed in Bundle");
20737        }
20738
20739        final long origId = Binder.clearCallingIdentity();
20740        try {
20741            boolean doNext = false;
20742            BroadcastRecord r;
20743
20744            synchronized(this) {
20745                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
20746                        ? mFgBroadcastQueue : mBgBroadcastQueue;
20747                r = queue.getMatchingOrderedReceiver(who);
20748                if (r != null) {
20749                    doNext = r.queue.finishReceiverLocked(r, resultCode,
20750                        resultData, resultExtras, resultAbort, true);
20751                }
20752            }
20753
20754            if (doNext) {
20755                r.queue.processNextBroadcast(false);
20756            }
20757            trimApplications();
20758        } finally {
20759            Binder.restoreCallingIdentity(origId);
20760        }
20761    }
20762
20763    // =========================================================
20764    // INSTRUMENTATION
20765    // =========================================================
20766
20767    public boolean startInstrumentation(ComponentName className,
20768            String profileFile, int flags, Bundle arguments,
20769            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
20770            int userId, String abiOverride) {
20771        enforceNotIsolatedCaller("startInstrumentation");
20772        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20773                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
20774        // Refuse possible leaked file descriptors
20775        if (arguments != null && arguments.hasFileDescriptors()) {
20776            throw new IllegalArgumentException("File descriptors passed in Bundle");
20777        }
20778
20779        synchronized(this) {
20780            InstrumentationInfo ii = null;
20781            ApplicationInfo ai = null;
20782            try {
20783                ii = mContext.getPackageManager().getInstrumentationInfo(
20784                    className, STOCK_PM_FLAGS);
20785                ai = AppGlobals.getPackageManager().getApplicationInfo(
20786                        ii.targetPackage, STOCK_PM_FLAGS, userId);
20787            } catch (PackageManager.NameNotFoundException e) {
20788            } catch (RemoteException e) {
20789            }
20790            if (ii == null) {
20791                reportStartInstrumentationFailureLocked(watcher, className,
20792                        "Unable to find instrumentation info for: " + className);
20793                return false;
20794            }
20795            if (ai == null) {
20796                reportStartInstrumentationFailureLocked(watcher, className,
20797                        "Unable to find instrumentation target package: " + ii.targetPackage);
20798                return false;
20799            }
20800            if (!ai.hasCode()) {
20801                reportStartInstrumentationFailureLocked(watcher, className,
20802                        "Instrumentation target has no code: " + ii.targetPackage);
20803                return false;
20804            }
20805
20806            int match = mContext.getPackageManager().checkSignatures(
20807                    ii.targetPackage, ii.packageName);
20808            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
20809                String msg = "Permission Denial: starting instrumentation "
20810                        + className + " from pid="
20811                        + Binder.getCallingPid()
20812                        + ", uid=" + Binder.getCallingPid()
20813                        + " not allowed because package " + ii.packageName
20814                        + " does not have a signature matching the target "
20815                        + ii.targetPackage;
20816                reportStartInstrumentationFailureLocked(watcher, className, msg);
20817                throw new SecurityException(msg);
20818            }
20819
20820            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20821            activeInstr.mClass = className;
20822            String defProcess = ai.processName;;
20823            if (ii.targetProcesses == null) {
20824                activeInstr.mTargetProcesses = new String[]{ai.processName};
20825            } else if (ii.targetProcesses.equals("*")) {
20826                activeInstr.mTargetProcesses = new String[0];
20827            } else {
20828                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20829                defProcess = activeInstr.mTargetProcesses[0];
20830            }
20831            activeInstr.mTargetInfo = ai;
20832            activeInstr.mProfileFile = profileFile;
20833            activeInstr.mArguments = arguments;
20834            activeInstr.mWatcher = watcher;
20835            activeInstr.mUiAutomationConnection = uiAutomationConnection;
20836            activeInstr.mResultClass = className;
20837
20838            final long origId = Binder.clearCallingIdentity();
20839            // Instrumentation can kill and relaunch even persistent processes
20840            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20841                    "start instr");
20842            // Inform usage stats to make the target package active
20843            if (mUsageStatsService != null) {
20844                mUsageStatsService.reportEvent(ii.targetPackage, userId,
20845                        UsageEvents.Event.SYSTEM_INTERACTION);
20846            }
20847            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20848            app.instr = activeInstr;
20849            activeInstr.mFinished = false;
20850            activeInstr.mRunningProcesses.add(app);
20851            if (!mActiveInstrumentation.contains(activeInstr)) {
20852                mActiveInstrumentation.add(activeInstr);
20853            }
20854            Binder.restoreCallingIdentity(origId);
20855        }
20856
20857        return true;
20858    }
20859
20860    /**
20861     * Report errors that occur while attempting to start Instrumentation.  Always writes the
20862     * error to the logs, but if somebody is watching, send the report there too.  This enables
20863     * the "am" command to report errors with more information.
20864     *
20865     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
20866     * @param cn The component name of the instrumentation.
20867     * @param report The error report.
20868     */
20869    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20870            ComponentName cn, String report) {
20871        Slog.w(TAG, report);
20872        if (watcher != null) {
20873            Bundle results = new Bundle();
20874            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20875            results.putString("Error", report);
20876            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20877        }
20878    }
20879
20880    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20881        if (app.instr == null) {
20882            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20883            return;
20884        }
20885
20886        if (!app.instr.mFinished && results != null) {
20887            if (app.instr.mCurResults == null) {
20888                app.instr.mCurResults = new Bundle(results);
20889            } else {
20890                app.instr.mCurResults.putAll(results);
20891            }
20892        }
20893    }
20894
20895    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20896        int userId = UserHandle.getCallingUserId();
20897        // Refuse possible leaked file descriptors
20898        if (results != null && results.hasFileDescriptors()) {
20899            throw new IllegalArgumentException("File descriptors passed in Intent");
20900        }
20901
20902        synchronized(this) {
20903            ProcessRecord app = getRecordForAppLocked(target);
20904            if (app == null) {
20905                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20906                return;
20907            }
20908            final long origId = Binder.clearCallingIdentity();
20909            addInstrumentationResultsLocked(app, results);
20910            Binder.restoreCallingIdentity(origId);
20911        }
20912    }
20913
20914    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20915        if (app.instr == null) {
20916            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20917            return;
20918        }
20919
20920        if (!app.instr.mFinished) {
20921            if (app.instr.mWatcher != null) {
20922                Bundle finalResults = app.instr.mCurResults;
20923                if (finalResults != null) {
20924                    if (app.instr.mCurResults != null && results != null) {
20925                        finalResults.putAll(results);
20926                    }
20927                } else {
20928                    finalResults = results;
20929                }
20930                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20931                        app.instr.mClass, resultCode, finalResults);
20932            }
20933
20934            // Can't call out of the system process with a lock held, so post a message.
20935            if (app.instr.mUiAutomationConnection != null) {
20936                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20937                        app.instr.mUiAutomationConnection).sendToTarget();
20938            }
20939            app.instr.mFinished = true;
20940        }
20941
20942        app.instr.removeProcess(app);
20943        app.instr = null;
20944
20945        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20946                "finished inst");
20947    }
20948
20949    public void finishInstrumentation(IApplicationThread target,
20950            int resultCode, Bundle results) {
20951        int userId = UserHandle.getCallingUserId();
20952        // Refuse possible leaked file descriptors
20953        if (results != null && results.hasFileDescriptors()) {
20954            throw new IllegalArgumentException("File descriptors passed in Intent");
20955        }
20956
20957        synchronized(this) {
20958            ProcessRecord app = getRecordForAppLocked(target);
20959            if (app == null) {
20960                Slog.w(TAG, "finishInstrumentation: no app for " + target);
20961                return;
20962            }
20963            final long origId = Binder.clearCallingIdentity();
20964            finishInstrumentationLocked(app, resultCode, results);
20965            Binder.restoreCallingIdentity(origId);
20966        }
20967    }
20968
20969    // =========================================================
20970    // CONFIGURATION
20971    // =========================================================
20972
20973    public ConfigurationInfo getDeviceConfigurationInfo() {
20974        ConfigurationInfo config = new ConfigurationInfo();
20975        synchronized (this) {
20976            final Configuration globalConfig = getGlobalConfiguration();
20977            config.reqTouchScreen = globalConfig.touchscreen;
20978            config.reqKeyboardType = globalConfig.keyboard;
20979            config.reqNavigation = globalConfig.navigation;
20980            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20981                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20982                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20983            }
20984            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20985                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20986                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20987            }
20988            config.reqGlEsVersion = GL_ES_VERSION;
20989        }
20990        return config;
20991    }
20992
20993    ActivityStack getFocusedStack() {
20994        return mStackSupervisor.getFocusedStack();
20995    }
20996
20997    @Override
20998    public StackInfo getFocusedStackInfo() throws RemoteException {
20999        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
21000        long ident = Binder.clearCallingIdentity();
21001        try {
21002            synchronized (this) {
21003                ActivityStack focusedStack = getFocusedStack();
21004                if (focusedStack != null) {
21005                    return mStackSupervisor.getStackInfo(focusedStack.mStackId);
21006                }
21007                return null;
21008            }
21009        } finally {
21010            Binder.restoreCallingIdentity(ident);
21011        }
21012    }
21013
21014    public Configuration getConfiguration() {
21015        Configuration ci;
21016        synchronized(this) {
21017            ci = new Configuration(getGlobalConfiguration());
21018            ci.userSetLocale = false;
21019        }
21020        return ci;
21021    }
21022
21023    @Override
21024    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
21025        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
21026        synchronized (this) {
21027            mSuppressResizeConfigChanges = suppress;
21028        }
21029    }
21030
21031    /**
21032     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
21033     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
21034     *       activity and clearing the task at the same time.
21035     */
21036    @Override
21037    // TODO: API should just be about changing windowing modes...
21038    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
21039        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
21040                "moveTasksToFullscreenStack()");
21041        synchronized (this) {
21042            final long origId = Binder.clearCallingIdentity();
21043            try {
21044                final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
21045                if (stack != null){
21046                    if (!stack.isActivityTypeStandardOrUndefined()) {
21047                        throw new IllegalArgumentException(
21048                                "You can't move tasks from non-standard stacks.");
21049                    }
21050                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
21051                }
21052            } finally {
21053                Binder.restoreCallingIdentity(origId);
21054            }
21055        }
21056    }
21057
21058    @Override
21059    public void updatePersistentConfiguration(Configuration values) {
21060        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
21061        enforceWriteSettingsPermission("updatePersistentConfiguration()");
21062        if (values == null) {
21063            throw new NullPointerException("Configuration must not be null");
21064        }
21065
21066        int userId = UserHandle.getCallingUserId();
21067
21068        synchronized(this) {
21069            updatePersistentConfigurationLocked(values, userId);
21070        }
21071    }
21072
21073    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
21074        final long origId = Binder.clearCallingIdentity();
21075        try {
21076            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
21077        } finally {
21078            Binder.restoreCallingIdentity(origId);
21079        }
21080    }
21081
21082    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
21083        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
21084                FONT_SCALE, 1.0f, userId);
21085
21086        synchronized (this) {
21087            if (getGlobalConfiguration().fontScale == scaleFactor) {
21088                return;
21089            }
21090
21091            final Configuration configuration
21092                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
21093            configuration.fontScale = scaleFactor;
21094            updatePersistentConfigurationLocked(configuration, userId);
21095        }
21096    }
21097
21098    private void enforceWriteSettingsPermission(String func) {
21099        int uid = Binder.getCallingUid();
21100        if (uid == ROOT_UID) {
21101            return;
21102        }
21103
21104        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
21105                Settings.getPackageNameForUid(mContext, uid), false)) {
21106            return;
21107        }
21108
21109        String msg = "Permission Denial: " + func + " from pid="
21110                + Binder.getCallingPid()
21111                + ", uid=" + uid
21112                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
21113        Slog.w(TAG, msg);
21114        throw new SecurityException(msg);
21115    }
21116
21117    @Override
21118    public boolean updateConfiguration(Configuration values) {
21119        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
21120
21121        synchronized(this) {
21122            if (values == null && mWindowManager != null) {
21123                // sentinel: fetch the current configuration from the window manager
21124                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
21125            }
21126
21127            if (mWindowManager != null) {
21128                // Update OOM levels based on display size.
21129                mProcessList.applyDisplaySize(mWindowManager);
21130            }
21131
21132            final long origId = Binder.clearCallingIdentity();
21133            try {
21134                if (values != null) {
21135                    Settings.System.clearConfiguration(values);
21136                }
21137                updateConfigurationLocked(values, null, false, false /* persistent */,
21138                        UserHandle.USER_NULL, false /* deferResume */,
21139                        mTmpUpdateConfigurationResult);
21140                return mTmpUpdateConfigurationResult.changes != 0;
21141            } finally {
21142                Binder.restoreCallingIdentity(origId);
21143            }
21144        }
21145    }
21146
21147    void updateUserConfigurationLocked() {
21148        final Configuration configuration = new Configuration(getGlobalConfiguration());
21149        final int currentUserId = mUserController.getCurrentUserId();
21150        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
21151                currentUserId, Settings.System.canWrite(mContext));
21152        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
21153                false /* persistent */, currentUserId, false /* deferResume */);
21154    }
21155
21156    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21157            boolean initLocale) {
21158        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
21159    }
21160
21161    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21162            boolean initLocale, boolean deferResume) {
21163        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
21164        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
21165                UserHandle.USER_NULL, deferResume);
21166    }
21167
21168    // To cache the list of supported system locales
21169    private String[] mSupportedSystemLocales = null;
21170
21171    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21172            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
21173        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
21174                deferResume, null /* result */);
21175    }
21176
21177    /**
21178     * Do either or both things: (1) change the current configuration, and (2)
21179     * make sure the given activity is running with the (now) current
21180     * configuration.  Returns true if the activity has been left running, or
21181     * false if <var>starting</var> is being destroyed to match the new
21182     * configuration.
21183     *
21184     * @param userId is only used when persistent parameter is set to true to persist configuration
21185     *               for that particular user
21186     */
21187    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
21188            boolean initLocale, boolean persistent, int userId, boolean deferResume,
21189            UpdateConfigurationResult result) {
21190        int changes = 0;
21191        boolean kept = true;
21192
21193        if (mWindowManager != null) {
21194            mWindowManager.deferSurfaceLayout();
21195        }
21196        try {
21197            if (values != null) {
21198                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
21199                        deferResume);
21200            }
21201
21202            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
21203        } finally {
21204            if (mWindowManager != null) {
21205                mWindowManager.continueSurfaceLayout();
21206            }
21207        }
21208
21209        if (result != null) {
21210            result.changes = changes;
21211            result.activityRelaunched = !kept;
21212        }
21213        return kept;
21214    }
21215
21216    /** Update default (global) configuration and notify listeners about changes. */
21217    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
21218            boolean persistent, int userId, boolean deferResume) {
21219        mTempConfig.setTo(getGlobalConfiguration());
21220        final int changes = mTempConfig.updateFrom(values);
21221        if (changes == 0) {
21222            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
21223            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
21224            // performDisplayOverrideConfigUpdate in order to send the new display configuration
21225            // (even if there are no actual changes) to unfreeze the window.
21226            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
21227            return 0;
21228        }
21229
21230        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
21231                "Updating global configuration to: " + values);
21232
21233        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
21234
21235        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
21236            final LocaleList locales = values.getLocales();
21237            int bestLocaleIndex = 0;
21238            if (locales.size() > 1) {
21239                if (mSupportedSystemLocales == null) {
21240                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
21241                }
21242                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
21243            }
21244            SystemProperties.set("persist.sys.locale",
21245                    locales.get(bestLocaleIndex).toLanguageTag());
21246            LocaleList.setDefault(locales, bestLocaleIndex);
21247            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
21248                    locales.get(bestLocaleIndex)));
21249        }
21250
21251        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
21252        mTempConfig.seq = mConfigurationSeq;
21253
21254        // Update stored global config and notify everyone about the change.
21255        mStackSupervisor.onConfigurationChanged(mTempConfig);
21256
21257        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
21258        // TODO(multi-display): Update UsageEvents#Event to include displayId.
21259        mUsageStatsService.reportConfigurationChange(mTempConfig,
21260                mUserController.getCurrentUserId());
21261
21262        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
21263        mShowDialogs = shouldShowDialogs(mTempConfig);
21264
21265        AttributeCache ac = AttributeCache.instance();
21266        if (ac != null) {
21267            ac.updateConfiguration(mTempConfig);
21268        }
21269
21270        // Make sure all resources in our process are updated right now, so that anyone who is going
21271        // to retrieve resource values after we return will be sure to get the new ones. This is
21272        // especially important during boot, where the first config change needs to guarantee all
21273        // resources have that config before following boot code is executed.
21274        mSystemThread.applyConfigurationToResources(mTempConfig);
21275
21276        // We need another copy of global config because we're scheduling some calls instead of
21277        // running them in place. We need to be sure that object we send will be handled unchanged.
21278        final Configuration configCopy = new Configuration(mTempConfig);
21279        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
21280            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
21281            msg.obj = configCopy;
21282            msg.arg1 = userId;
21283            mHandler.sendMessage(msg);
21284        }
21285
21286        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21287            ProcessRecord app = mLruProcesses.get(i);
21288            try {
21289                if (app.thread != null) {
21290                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
21291                            + app.processName + " new config " + configCopy);
21292                    mLifecycleManager.scheduleTransaction(app.thread,
21293                            ConfigurationChangeItem.obtain(configCopy));
21294                }
21295            } catch (Exception e) {
21296                Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
21297            }
21298        }
21299
21300        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
21301        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
21302                | Intent.FLAG_RECEIVER_FOREGROUND
21303                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21304        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
21305                OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
21306                UserHandle.USER_ALL);
21307        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
21308            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
21309            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
21310                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
21311                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21312            if (initLocale || !mProcessesReady) {
21313                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21314            }
21315            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
21316                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
21317                    UserHandle.USER_ALL);
21318        }
21319
21320        // Override configuration of the default display duplicates global config, so we need to
21321        // update it also. This will also notify WindowManager about changes.
21322        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
21323                DEFAULT_DISPLAY);
21324
21325        return changes;
21326    }
21327
21328    @Override
21329    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
21330        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
21331
21332        synchronized (this) {
21333            // Check if display is initialized in AM.
21334            if (!mStackSupervisor.isDisplayAdded(displayId)) {
21335                // Call might come when display is not yet added or has already been removed.
21336                if (DEBUG_CONFIGURATION) {
21337                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
21338                            + displayId);
21339                }
21340                return false;
21341            }
21342
21343            if (values == null && mWindowManager != null) {
21344                // sentinel: fetch the current configuration from the window manager
21345                values = mWindowManager.computeNewConfiguration(displayId);
21346            }
21347
21348            if (mWindowManager != null) {
21349                // Update OOM levels based on display size.
21350                mProcessList.applyDisplaySize(mWindowManager);
21351            }
21352
21353            final long origId = Binder.clearCallingIdentity();
21354            try {
21355                if (values != null) {
21356                    Settings.System.clearConfiguration(values);
21357                }
21358                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
21359                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
21360                return mTmpUpdateConfigurationResult.changes != 0;
21361            } finally {
21362                Binder.restoreCallingIdentity(origId);
21363            }
21364        }
21365    }
21366
21367    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
21368            boolean deferResume, int displayId) {
21369        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
21370                displayId, null /* result */);
21371    }
21372
21373    /**
21374     * Updates override configuration specific for the selected display. If no config is provided,
21375     * new one will be computed in WM based on current display info.
21376     */
21377    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
21378            ActivityRecord starting, boolean deferResume, int displayId,
21379            UpdateConfigurationResult result) {
21380        int changes = 0;
21381        boolean kept = true;
21382
21383        if (mWindowManager != null) {
21384            mWindowManager.deferSurfaceLayout();
21385        }
21386        try {
21387            if (values != null) {
21388                if (displayId == DEFAULT_DISPLAY) {
21389                    // Override configuration of the default display duplicates global config, so
21390                    // we're calling global config update instead for default display. It will also
21391                    // apply the correct override config.
21392                    changes = updateGlobalConfiguration(values, false /* initLocale */,
21393                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
21394                } else {
21395                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
21396                }
21397            }
21398
21399            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
21400        } finally {
21401            if (mWindowManager != null) {
21402                mWindowManager.continueSurfaceLayout();
21403            }
21404        }
21405
21406        if (result != null) {
21407            result.changes = changes;
21408            result.activityRelaunched = !kept;
21409        }
21410        return kept;
21411    }
21412
21413    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
21414            int displayId) {
21415        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
21416        final int changes = mTempConfig.updateFrom(values);
21417        if (changes != 0) {
21418            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
21419                    + mTempConfig + " for displayId=" + displayId);
21420            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
21421
21422            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
21423            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
21424                mAppWarnings.onDensityChanged();
21425
21426                killAllBackgroundProcessesExcept(N,
21427                        ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
21428            }
21429        }
21430
21431        // Update the configuration with WM first and check if any of the stacks need to be resized
21432        // due to the configuration change. If so, resize the stacks now and do any relaunches if
21433        // necessary. This way we don't need to relaunch again afterwards in
21434        // ensureActivityConfigurationLocked().
21435        if (mWindowManager != null) {
21436            final int[] resizedStacks =
21437                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
21438            if (resizedStacks != null) {
21439                for (int stackId : resizedStacks) {
21440                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
21441                }
21442            }
21443        }
21444
21445        return changes;
21446    }
21447
21448    /** Applies latest configuration and/or visibility updates if needed. */
21449    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
21450        boolean kept = true;
21451        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
21452        // mainStack is null during startup.
21453        if (mainStack != null) {
21454            if (changes != 0 && starting == null) {
21455                // If the configuration changed, and the caller is not already
21456                // in the process of starting an activity, then find the top
21457                // activity to check if its configuration needs to change.
21458                starting = mainStack.topRunningActivityLocked();
21459            }
21460
21461            if (starting != null) {
21462                kept = starting.ensureActivityConfigurationLocked(changes,
21463                        false /* preserveWindow */);
21464                // And we need to make sure at this point that all other activities
21465                // are made visible with the correct configuration.
21466                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
21467                        !PRESERVE_WINDOWS);
21468            }
21469        }
21470
21471        return kept;
21472    }
21473
21474    /** Helper method that requests bounds from WM and applies them to stack. */
21475    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
21476        final Rect newStackBounds = new Rect();
21477        final ActivityStack stack = mStackSupervisor.getStack(stackId);
21478        stack.getBoundsForNewConfiguration(newStackBounds);
21479        mStackSupervisor.resizeStackLocked(
21480                stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
21481                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
21482                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
21483    }
21484
21485    /**
21486     * Decide based on the configuration whether we should show the ANR,
21487     * crash, etc dialogs.  The idea is that if there is no affordance to
21488     * press the on-screen buttons, or the user experience would be more
21489     * greatly impacted than the crash itself, we shouldn't show the dialog.
21490     *
21491     * A thought: SystemUI might also want to get told about this, the Power
21492     * dialog / global actions also might want different behaviors.
21493     */
21494    private static boolean shouldShowDialogs(Configuration config) {
21495        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
21496                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
21497                                   && config.navigation == Configuration.NAVIGATION_NONAV);
21498        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
21499        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
21500                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
21501                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
21502                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
21503        return inputMethodExists && uiModeSupportsDialogs;
21504    }
21505
21506    @Override
21507    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
21508        synchronized (this) {
21509            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
21510            if (srec != null) {
21511                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
21512            }
21513        }
21514        return false;
21515    }
21516
21517    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
21518            Intent resultData) {
21519
21520        synchronized (this) {
21521            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
21522            if (r != null) {
21523                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
21524            }
21525            return false;
21526        }
21527    }
21528
21529    public int getLaunchedFromUid(IBinder activityToken) {
21530        ActivityRecord srec;
21531        synchronized (this) {
21532            srec = ActivityRecord.forTokenLocked(activityToken);
21533        }
21534        if (srec == null) {
21535            return -1;
21536        }
21537        return srec.launchedFromUid;
21538    }
21539
21540    public String getLaunchedFromPackage(IBinder activityToken) {
21541        ActivityRecord srec;
21542        synchronized (this) {
21543            srec = ActivityRecord.forTokenLocked(activityToken);
21544        }
21545        if (srec == null) {
21546            return null;
21547        }
21548        return srec.launchedFromPackage;
21549    }
21550
21551    // =========================================================
21552    // LIFETIME MANAGEMENT
21553    // =========================================================
21554
21555    // Returns whether the app is receiving broadcast.
21556    // If receiving, fetch all broadcast queues which the app is
21557    // the current [or imminent] receiver on.
21558    private boolean isReceivingBroadcastLocked(ProcessRecord app,
21559            ArraySet<BroadcastQueue> receivingQueues) {
21560        final int N = app.curReceivers.size();
21561        if (N > 0) {
21562            for (int i = 0; i < N; i++) {
21563                receivingQueues.add(app.curReceivers.valueAt(i).queue);
21564            }
21565            return true;
21566        }
21567
21568        // It's not the current receiver, but it might be starting up to become one
21569        for (BroadcastQueue queue : mBroadcastQueues) {
21570            final BroadcastRecord r = queue.mPendingBroadcast;
21571            if (r != null && r.curApp == app) {
21572                // found it; report which queue it's in
21573                receivingQueues.add(queue);
21574            }
21575        }
21576
21577        return !receivingQueues.isEmpty();
21578    }
21579
21580    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
21581            int targetUid, ComponentName targetComponent, String targetProcess) {
21582        if (!mTrackingAssociations) {
21583            return null;
21584        }
21585        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
21586                = mAssociations.get(targetUid);
21587        if (components == null) {
21588            components = new ArrayMap<>();
21589            mAssociations.put(targetUid, components);
21590        }
21591        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
21592        if (sourceUids == null) {
21593            sourceUids = new SparseArray<>();
21594            components.put(targetComponent, sourceUids);
21595        }
21596        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
21597        if (sourceProcesses == null) {
21598            sourceProcesses = new ArrayMap<>();
21599            sourceUids.put(sourceUid, sourceProcesses);
21600        }
21601        Association ass = sourceProcesses.get(sourceProcess);
21602        if (ass == null) {
21603            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
21604                    targetProcess);
21605            sourceProcesses.put(sourceProcess, ass);
21606        }
21607        ass.mCount++;
21608        ass.mNesting++;
21609        if (ass.mNesting == 1) {
21610            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
21611            ass.mLastState = sourceState;
21612        }
21613        return ass;
21614    }
21615
21616    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
21617            ComponentName targetComponent) {
21618        if (!mTrackingAssociations) {
21619            return;
21620        }
21621        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
21622                = mAssociations.get(targetUid);
21623        if (components == null) {
21624            return;
21625        }
21626        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
21627        if (sourceUids == null) {
21628            return;
21629        }
21630        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
21631        if (sourceProcesses == null) {
21632            return;
21633        }
21634        Association ass = sourceProcesses.get(sourceProcess);
21635        if (ass == null || ass.mNesting <= 0) {
21636            return;
21637        }
21638        ass.mNesting--;
21639        if (ass.mNesting == 0) {
21640            long uptime = SystemClock.uptimeMillis();
21641            ass.mTime += uptime - ass.mStartTime;
21642            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
21643                    += uptime - ass.mLastStateUptime;
21644            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
21645        }
21646    }
21647
21648    private void noteUidProcessState(final int uid, final int state) {
21649        mBatteryStatsService.noteUidProcessState(uid, state);
21650        if (mTrackingAssociations) {
21651            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
21652                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
21653                        = mAssociations.valueAt(i1);
21654                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
21655                    SparseArray<ArrayMap<String, Association>> sourceUids
21656                            = targetComponents.valueAt(i2);
21657                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
21658                    if (sourceProcesses != null) {
21659                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
21660                            Association ass = sourceProcesses.valueAt(i4);
21661                            if (ass.mNesting >= 1) {
21662                                // currently associated
21663                                long uptime = SystemClock.uptimeMillis();
21664                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
21665                                        += uptime - ass.mLastStateUptime;
21666                                ass.mLastState = state;
21667                                ass.mLastStateUptime = uptime;
21668                            }
21669                        }
21670                    }
21671                }
21672            }
21673        }
21674    }
21675
21676    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
21677            boolean doingAll, long now) {
21678        if (mAdjSeq == app.adjSeq) {
21679            // This adjustment has already been computed.
21680            return app.curRawAdj;
21681        }
21682
21683        if (app.thread == null) {
21684            app.adjSeq = mAdjSeq;
21685            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21686            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21687            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
21688        }
21689
21690        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
21691        app.adjSource = null;
21692        app.adjTarget = null;
21693        app.empty = false;
21694        app.cached = false;
21695
21696        final int activitiesSize = app.activities.size();
21697
21698        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
21699            // The max adjustment doesn't allow this app to be anything
21700            // below foreground, so it is not worth doing work for it.
21701            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
21702            app.adjType = "fixed";
21703            app.adjSeq = mAdjSeq;
21704            app.curRawAdj = app.maxAdj;
21705            app.foregroundActivities = false;
21706            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21707            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
21708            // System processes can do UI, and when they do we want to have
21709            // them trim their memory after the user leaves the UI.  To
21710            // facilitate this, here we need to determine whether or not it
21711            // is currently showing UI.
21712            app.systemNoUi = true;
21713            if (app == TOP_APP) {
21714                app.systemNoUi = false;
21715                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
21716                app.adjType = "pers-top-activity";
21717            } else if (app.hasTopUi) {
21718                app.systemNoUi = false;
21719                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
21720                app.adjType = "pers-top-ui";
21721            } else if (activitiesSize > 0) {
21722                for (int j = 0; j < activitiesSize; j++) {
21723                    final ActivityRecord r = app.activities.get(j);
21724                    if (r.visible) {
21725                        app.systemNoUi = false;
21726                    }
21727                }
21728            }
21729            if (!app.systemNoUi) {
21730                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
21731            }
21732            return (app.curAdj=app.maxAdj);
21733        }
21734
21735        app.systemNoUi = false;
21736
21737        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
21738
21739        // Determine the importance of the process, starting with most
21740        // important to least, and assign an appropriate OOM adjustment.
21741        int adj;
21742        int schedGroup;
21743        int procState;
21744        boolean foregroundActivities = false;
21745        mTmpBroadcastQueue.clear();
21746        if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
21747            // The last app on the list is the foreground app.
21748            adj = ProcessList.FOREGROUND_APP_ADJ;
21749            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
21750            app.adjType = "top-activity";
21751            foregroundActivities = true;
21752            procState = PROCESS_STATE_CUR_TOP;
21753            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
21754        } else if (app.instr != null) {
21755            // Don't want to kill running instrumentation.
21756            adj = ProcessList.FOREGROUND_APP_ADJ;
21757            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21758            app.adjType = "instrumentation";
21759            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21760            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
21761        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
21762            // An app that is currently receiving a broadcast also
21763            // counts as being in the foreground for OOM killer purposes.
21764            // It's placed in a sched group based on the nature of the
21765            // broadcast as reflected by which queue it's active in.
21766            adj = ProcessList.FOREGROUND_APP_ADJ;
21767            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
21768                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
21769            app.adjType = "broadcast";
21770            procState = ActivityManager.PROCESS_STATE_RECEIVER;
21771            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
21772        } else if (app.executingServices.size() > 0) {
21773            // An app that is currently executing a service callback also
21774            // counts as being in the foreground.
21775            adj = ProcessList.FOREGROUND_APP_ADJ;
21776            schedGroup = app.execServicesFg ?
21777                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
21778            app.adjType = "exec-service";
21779            procState = ActivityManager.PROCESS_STATE_SERVICE;
21780            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
21781            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
21782        } else if (app == TOP_APP) {
21783            adj = ProcessList.FOREGROUND_APP_ADJ;
21784            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21785            app.adjType = "top-sleeping";
21786            foregroundActivities = true;
21787            procState = PROCESS_STATE_CUR_TOP;
21788            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
21789        } else {
21790            // As far as we know the process is empty.  We may change our mind later.
21791            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21792            // At this point we don't actually know the adjustment.  Use the cached adj
21793            // value that the caller wants us to.
21794            adj = cachedAdj;
21795            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21796            app.cached = true;
21797            app.empty = true;
21798            app.adjType = "cch-empty";
21799            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
21800        }
21801
21802        // Examine all activities if not already foreground.
21803        if (!foregroundActivities && activitiesSize > 0) {
21804            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
21805            for (int j = 0; j < activitiesSize; j++) {
21806                final ActivityRecord r = app.activities.get(j);
21807                if (r.app != app) {
21808                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
21809                            + " instead of expected " + app);
21810                    if (r.app == null || (r.app.uid == app.uid)) {
21811                        // Only fix things up when they look sane
21812                        r.setProcess(app);
21813                    } else {
21814                        continue;
21815                    }
21816                }
21817                if (r.visible) {
21818                    // App has a visible activity; only upgrade adjustment.
21819                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
21820                        adj = ProcessList.VISIBLE_APP_ADJ;
21821                        app.adjType = "vis-activity";
21822                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
21823                    }
21824                    if (procState > PROCESS_STATE_CUR_TOP) {
21825                        procState = PROCESS_STATE_CUR_TOP;
21826                        app.adjType = "vis-activity";
21827                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
21828                    }
21829                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21830                    app.cached = false;
21831                    app.empty = false;
21832                    foregroundActivities = true;
21833                    final TaskRecord task = r.getTask();
21834                    if (task != null && minLayer > 0) {
21835                        final int layer = task.mLayerRank;
21836                        if (layer >= 0 && minLayer > layer) {
21837                            minLayer = layer;
21838                        }
21839                    }
21840                    break;
21841                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
21842                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21843                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21844                        app.adjType = "pause-activity";
21845                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21846                    }
21847                    if (procState > PROCESS_STATE_CUR_TOP) {
21848                        procState = PROCESS_STATE_CUR_TOP;
21849                        app.adjType = "pause-activity";
21850                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21851                    }
21852                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21853                    app.cached = false;
21854                    app.empty = false;
21855                    foregroundActivities = true;
21856                } else if (r.state == ActivityState.STOPPING) {
21857                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21858                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21859                        app.adjType = "stop-activity";
21860                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21861                    }
21862                    // For the process state, we will at this point consider the
21863                    // process to be cached.  It will be cached either as an activity
21864                    // or empty depending on whether the activity is finishing.  We do
21865                    // this so that we can treat the process as cached for purposes of
21866                    // memory trimming (determing current memory level, trim command to
21867                    // send to process) since there can be an arbitrary number of stopping
21868                    // processes and they should soon all go into the cached state.
21869                    if (!r.finishing) {
21870                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21871                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21872                            app.adjType = "stop-activity";
21873                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21874                        }
21875                    }
21876                    app.cached = false;
21877                    app.empty = false;
21878                    foregroundActivities = true;
21879                } else {
21880                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21881                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21882                        app.adjType = "cch-act";
21883                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21884                    }
21885                }
21886            }
21887            if (adj == ProcessList.VISIBLE_APP_ADJ) {
21888                adj += minLayer;
21889            }
21890        }
21891        if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) {
21892            procState = ActivityManager.PROCESS_STATE_CACHED_RECENT;
21893            app.adjType = "cch-rec";
21894            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached recent: " + app);
21895        }
21896
21897        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21898                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21899            if (app.foregroundServices) {
21900                // The user is aware of this app, so make it visible.
21901                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21902                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21903                app.cached = false;
21904                app.adjType = "fg-service";
21905                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21906                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21907            } else if (app.hasOverlayUi) {
21908                // The process is display an overlay UI.
21909                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21910                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21911                app.cached = false;
21912                app.adjType = "has-overlay-ui";
21913                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21914                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21915            }
21916        }
21917
21918        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21919                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21920            if (app.forcingToImportant != null) {
21921                // This is currently used for toasts...  they are not interactive, and
21922                // we don't want them to cause the app to become fully foreground (and
21923                // thus out of background check), so we yes the best background level we can.
21924                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21925                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21926                app.cached = false;
21927                app.adjType = "force-imp";
21928                app.adjSource = app.forcingToImportant;
21929                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21930                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21931            }
21932        }
21933
21934        if (app == mHeavyWeightProcess) {
21935            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21936                // We don't want to kill the current heavy-weight process.
21937                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21938                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21939                app.cached = false;
21940                app.adjType = "heavy";
21941                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21942            }
21943            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21944                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21945                app.adjType = "heavy";
21946                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21947            }
21948        }
21949
21950        if (app == mHomeProcess) {
21951            if (adj > ProcessList.HOME_APP_ADJ) {
21952                // This process is hosting what we currently consider to be the
21953                // home app, so we don't want to let it go into the background.
21954                adj = ProcessList.HOME_APP_ADJ;
21955                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21956                app.cached = false;
21957                app.adjType = "home";
21958                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21959            }
21960            if (procState > ActivityManager.PROCESS_STATE_HOME) {
21961                procState = ActivityManager.PROCESS_STATE_HOME;
21962                app.adjType = "home";
21963                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21964            }
21965        }
21966
21967        if (app == mPreviousProcess && app.activities.size() > 0) {
21968            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21969                // This was the previous process that showed UI to the user.
21970                // We want to try to keep it around more aggressively, to give
21971                // a good experience around switching between two apps.
21972                adj = ProcessList.PREVIOUS_APP_ADJ;
21973                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21974                app.cached = false;
21975                app.adjType = "previous";
21976                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21977            }
21978            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21979                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21980                app.adjType = "previous";
21981                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21982            }
21983        }
21984
21985        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21986                + " reason=" + app.adjType);
21987
21988        // By default, we use the computed adjustment.  It may be changed if
21989        // there are applications dependent on our services or providers, but
21990        // this gives us a baseline and makes sure we don't get into an
21991        // infinite recursion.
21992        app.adjSeq = mAdjSeq;
21993        app.curRawAdj = adj;
21994        app.hasStartedServices = false;
21995
21996        if (mBackupTarget != null && app == mBackupTarget.app) {
21997            // If possible we want to avoid killing apps while they're being backed up
21998            if (adj > ProcessList.BACKUP_APP_ADJ) {
21999                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
22000                adj = ProcessList.BACKUP_APP_ADJ;
22001                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22002                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22003                }
22004                app.adjType = "backup";
22005                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
22006                app.cached = false;
22007            }
22008            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
22009                procState = ActivityManager.PROCESS_STATE_BACKUP;
22010                app.adjType = "backup";
22011                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
22012            }
22013        }
22014
22015        boolean mayBeTop = false;
22016        String mayBeTopType = null;
22017        Object mayBeTopSource = null;
22018        Object mayBeTopTarget = null;
22019
22020        for (int is = app.services.size()-1;
22021                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22022                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22023                        || procState > ActivityManager.PROCESS_STATE_TOP);
22024                is--) {
22025            ServiceRecord s = app.services.valueAt(is);
22026            if (s.startRequested) {
22027                app.hasStartedServices = true;
22028                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
22029                    procState = ActivityManager.PROCESS_STATE_SERVICE;
22030                    app.adjType = "started-services";
22031                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
22032                }
22033                if (app.hasShownUi && app != mHomeProcess) {
22034                    // If this process has shown some UI, let it immediately
22035                    // go to the LRU list because it may be pretty heavy with
22036                    // UI stuff.  We'll tag it with a label just to help
22037                    // debug and understand what is going on.
22038                    if (adj > ProcessList.SERVICE_ADJ) {
22039                        app.adjType = "cch-started-ui-services";
22040                    }
22041                } else {
22042                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
22043                        // This service has seen some activity within
22044                        // recent memory, so we will keep its process ahead
22045                        // of the background processes.
22046                        if (adj > ProcessList.SERVICE_ADJ) {
22047                            adj = ProcessList.SERVICE_ADJ;
22048                            app.adjType = "started-services";
22049                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
22050                            app.cached = false;
22051                        }
22052                    }
22053                    // If we have let the service slide into the background
22054                    // state, still have some text describing what it is doing
22055                    // even though the service no longer has an impact.
22056                    if (adj > ProcessList.SERVICE_ADJ) {
22057                        app.adjType = "cch-started-services";
22058                    }
22059                }
22060            }
22061
22062            for (int conni = s.connections.size()-1;
22063                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22064                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22065                            || procState > ActivityManager.PROCESS_STATE_TOP);
22066                    conni--) {
22067                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
22068                for (int i = 0;
22069                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
22070                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22071                                || procState > ActivityManager.PROCESS_STATE_TOP);
22072                        i++) {
22073                    // XXX should compute this based on the max of
22074                    // all connected clients.
22075                    ConnectionRecord cr = clist.get(i);
22076                    if (cr.binding.client == app) {
22077                        // Binding to ourself is not interesting.
22078                        continue;
22079                    }
22080
22081                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
22082                        ProcessRecord client = cr.binding.client;
22083                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
22084                                TOP_APP, doingAll, now);
22085                        int clientProcState = client.curProcState;
22086                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22087                            // If the other app is cached for any reason, for purposes here
22088                            // we are going to consider it empty.  The specific cached state
22089                            // doesn't propagate except under certain conditions.
22090                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22091                        }
22092                        String adjType = null;
22093                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
22094                            // Not doing bind OOM management, so treat
22095                            // this guy more like a started service.
22096                            if (app.hasShownUi && app != mHomeProcess) {
22097                                // If this process has shown some UI, let it immediately
22098                                // go to the LRU list because it may be pretty heavy with
22099                                // UI stuff.  We'll tag it with a label just to help
22100                                // debug and understand what is going on.
22101                                if (adj > clientAdj) {
22102                                    adjType = "cch-bound-ui-services";
22103                                }
22104                                app.cached = false;
22105                                clientAdj = adj;
22106                                clientProcState = procState;
22107                            } else {
22108                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
22109                                    // This service has not seen activity within
22110                                    // recent memory, so allow it to drop to the
22111                                    // LRU list if there is no other reason to keep
22112                                    // it around.  We'll also tag it with a label just
22113                                    // to help debug and undertand what is going on.
22114                                    if (adj > clientAdj) {
22115                                        adjType = "cch-bound-services";
22116                                    }
22117                                    clientAdj = adj;
22118                                }
22119                            }
22120                        }
22121                        if (adj > clientAdj) {
22122                            // If this process has recently shown UI, and
22123                            // the process that is binding to it is less
22124                            // important than being visible, then we don't
22125                            // care about the binding as much as we care
22126                            // about letting this process get into the LRU
22127                            // list to be killed and restarted if needed for
22128                            // memory.
22129                            if (app.hasShownUi && app != mHomeProcess
22130                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22131                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
22132                                    adjType = "cch-bound-ui-services";
22133                                }
22134                            } else {
22135                                int newAdj;
22136                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
22137                                        |Context.BIND_IMPORTANT)) != 0) {
22138                                    newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
22139                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
22140                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
22141                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
22142                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22143                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
22144                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
22145                                    newAdj = clientAdj;
22146                                } else {
22147                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
22148                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
22149                                    } else {
22150                                        newAdj = adj;
22151                                    }
22152                                }
22153                                if (!client.cached) {
22154                                    app.cached = false;
22155                                }
22156                                if (adj >  newAdj) {
22157                                    adj = newAdj;
22158                                    adjType = "service";
22159                                }
22160                            }
22161                        }
22162                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
22163                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
22164                            // This will treat important bound services identically to
22165                            // the top app, which may behave differently than generic
22166                            // foreground work.
22167                            if (client.curSchedGroup > schedGroup) {
22168                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
22169                                    schedGroup = client.curSchedGroup;
22170                                } else {
22171                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22172                                }
22173                            }
22174                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
22175                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
22176                                    // Special handling of clients who are in the top state.
22177                                    // We *may* want to consider this process to be in the
22178                                    // top state as well, but only if there is not another
22179                                    // reason for it to be running.  Being on the top is a
22180                                    // special state, meaning you are specifically running
22181                                    // for the current top app.  If the process is already
22182                                    // running in the background for some other reason, it
22183                                    // is more important to continue considering it to be
22184                                    // in the background state.
22185                                    mayBeTop = true;
22186                                    mayBeTopType = "service";
22187                                    mayBeTopSource = cr.binding.client;
22188                                    mayBeTopTarget = s.name;
22189                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22190                                } else {
22191                                    // Special handling for above-top states (persistent
22192                                    // processes).  These should not bring the current process
22193                                    // into the top state, since they are not on top.  Instead
22194                                    // give them the best state after that.
22195                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
22196                                        clientProcState =
22197                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
22198                                    } else if (mWakefulness
22199                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
22200                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
22201                                                    != 0) {
22202                                        clientProcState =
22203                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
22204                                    } else {
22205                                        clientProcState =
22206                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22207                                    }
22208                                }
22209                            }
22210                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
22211                            if (clientProcState <
22212                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22213                                clientProcState =
22214                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22215                            }
22216                        } else {
22217                            if (clientProcState <
22218                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
22219                                clientProcState =
22220                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
22221                            }
22222                        }
22223                        if (procState > clientProcState) {
22224                            procState = clientProcState;
22225                            if (adjType == null) {
22226                                adjType = "service";
22227                            }
22228                        }
22229                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22230                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
22231                            app.pendingUiClean = true;
22232                        }
22233                        if (adjType != null) {
22234                            app.adjType = adjType;
22235                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
22236                                    .REASON_SERVICE_IN_USE;
22237                            app.adjSource = cr.binding.client;
22238                            app.adjSourceProcState = clientProcState;
22239                            app.adjTarget = s.name;
22240                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
22241                                    + ": " + app + ", due to " + cr.binding.client
22242                                    + " adj=" + adj + " procState=" + procState);
22243                        }
22244                    }
22245                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
22246                        app.treatLikeActivity = true;
22247                    }
22248                    final ActivityRecord a = cr.activity;
22249                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
22250                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
22251                            (a.visible || a.state == ActivityState.RESUMED ||
22252                             a.state == ActivityState.PAUSING)) {
22253                            adj = ProcessList.FOREGROUND_APP_ADJ;
22254                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
22255                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
22256                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
22257                                } else {
22258                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22259                                }
22260                            }
22261                            app.cached = false;
22262                            app.adjType = "service";
22263                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
22264                                    .REASON_SERVICE_IN_USE;
22265                            app.adjSource = a;
22266                            app.adjSourceProcState = procState;
22267                            app.adjTarget = s.name;
22268                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
22269                                    + app);
22270                        }
22271                    }
22272                }
22273            }
22274        }
22275
22276        for (int provi = app.pubProviders.size()-1;
22277                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22278                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22279                        || procState > ActivityManager.PROCESS_STATE_TOP);
22280                provi--) {
22281            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
22282            for (int i = cpr.connections.size()-1;
22283                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
22284                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
22285                            || procState > ActivityManager.PROCESS_STATE_TOP);
22286                    i--) {
22287                ContentProviderConnection conn = cpr.connections.get(i);
22288                ProcessRecord client = conn.client;
22289                if (client == app) {
22290                    // Being our own client is not interesting.
22291                    continue;
22292                }
22293                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
22294                int clientProcState = client.curProcState;
22295                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22296                    // If the other app is cached for any reason, for purposes here
22297                    // we are going to consider it empty.
22298                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22299                }
22300                String adjType = null;
22301                if (adj > clientAdj) {
22302                    if (app.hasShownUi && app != mHomeProcess
22303                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22304                        adjType = "cch-ui-provider";
22305                    } else {
22306                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
22307                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
22308                        adjType = "provider";
22309                    }
22310                    app.cached &= client.cached;
22311                }
22312                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
22313                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
22314                        // Special handling of clients who are in the top state.
22315                        // We *may* want to consider this process to be in the
22316                        // top state as well, but only if there is not another
22317                        // reason for it to be running.  Being on the top is a
22318                        // special state, meaning you are specifically running
22319                        // for the current top app.  If the process is already
22320                        // running in the background for some other reason, it
22321                        // is more important to continue considering it to be
22322                        // in the background state.
22323                        mayBeTop = true;
22324                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22325                        mayBeTopType = adjType = "provider-top";
22326                        mayBeTopSource = client;
22327                        mayBeTopTarget = cpr.name;
22328                    } else {
22329                        // Special handling for above-top states (persistent
22330                        // processes).  These should not bring the current process
22331                        // into the top state, since they are not on top.  Instead
22332                        // give them the best state after that.
22333                        clientProcState =
22334                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
22335                        if (adjType == null) {
22336                            adjType = "provider";
22337                        }
22338                    }
22339                }
22340                if (procState > clientProcState) {
22341                    procState = clientProcState;
22342                }
22343                if (client.curSchedGroup > schedGroup) {
22344                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22345                }
22346                if (adjType != null) {
22347                    app.adjType = adjType;
22348                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
22349                            .REASON_PROVIDER_IN_USE;
22350                    app.adjSource = client;
22351                    app.adjSourceProcState = clientProcState;
22352                    app.adjTarget = cpr.name;
22353                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
22354                            + ": " + app + ", due to " + client
22355                            + " adj=" + adj + " procState=" + procState);
22356                }
22357            }
22358            // If the provider has external (non-framework) process
22359            // dependencies, ensure that its adjustment is at least
22360            // FOREGROUND_APP_ADJ.
22361            if (cpr.hasExternalProcessHandles()) {
22362                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
22363                    adj = ProcessList.FOREGROUND_APP_ADJ;
22364                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22365                    app.cached = false;
22366                    app.adjType = "ext-provider";
22367                    app.adjTarget = cpr.name;
22368                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
22369                }
22370                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22371                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22372                }
22373            }
22374        }
22375
22376        if (app.lastProviderTime > 0 &&
22377                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
22378            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
22379                adj = ProcessList.PREVIOUS_APP_ADJ;
22380                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22381                app.cached = false;
22382                app.adjType = "recent-provider";
22383                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
22384            }
22385            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
22386                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
22387                app.adjType = "recent-provider";
22388                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
22389            }
22390        }
22391
22392        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
22393            // A client of one of our services or providers is in the top state.  We
22394            // *may* want to be in the top state, but not if we are already running in
22395            // the background for some other reason.  For the decision here, we are going
22396            // to pick out a few specific states that we want to remain in when a client
22397            // is top (states that tend to be longer-term) and otherwise allow it to go
22398            // to the top state.
22399            switch (procState) {
22400                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
22401                case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
22402                    // Something else is keeping it at this level, just leave it.
22403                    break;
22404                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
22405                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
22406                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
22407                case ActivityManager.PROCESS_STATE_SERVICE:
22408                    // These all are longer-term states, so pull them up to the top
22409                    // of the background states, but not all the way to the top state.
22410                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
22411                    app.adjType = mayBeTopType;
22412                    app.adjSource = mayBeTopSource;
22413                    app.adjTarget = mayBeTopTarget;
22414                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
22415                            + ": " + app + ", due to " + mayBeTopSource
22416                            + " adj=" + adj + " procState=" + procState);
22417                    break;
22418                default:
22419                    // Otherwise, top is a better choice, so take it.
22420                    procState = ActivityManager.PROCESS_STATE_TOP;
22421                    app.adjType = mayBeTopType;
22422                    app.adjSource = mayBeTopSource;
22423                    app.adjTarget = mayBeTopTarget;
22424                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
22425                            + ": " + app + ", due to " + mayBeTopSource
22426                            + " adj=" + adj + " procState=" + procState);
22427                    break;
22428            }
22429        }
22430
22431        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
22432            if (app.hasClientActivities) {
22433                // This is a cached process, but with client activities.  Mark it so.
22434                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
22435                app.adjType = "cch-client-act";
22436            } else if (app.treatLikeActivity) {
22437                // This is a cached process, but somebody wants us to treat it like it has
22438                // an activity, okay!
22439                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
22440                app.adjType = "cch-as-act";
22441            }
22442        }
22443
22444        if (adj == ProcessList.SERVICE_ADJ) {
22445            if (doingAll) {
22446                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
22447                mNewNumServiceProcs++;
22448                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
22449                if (!app.serviceb) {
22450                    // This service isn't far enough down on the LRU list to
22451                    // normally be a B service, but if we are low on RAM and it
22452                    // is large we want to force it down since we would prefer to
22453                    // keep launcher over it.
22454                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
22455                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
22456                        app.serviceHighRam = true;
22457                        app.serviceb = true;
22458                        //Slog.i(TAG, "ADJ " + app + " high ram!");
22459                    } else {
22460                        mNewNumAServiceProcs++;
22461                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
22462                    }
22463                } else {
22464                    app.serviceHighRam = false;
22465                }
22466            }
22467            if (app.serviceb) {
22468                adj = ProcessList.SERVICE_B_ADJ;
22469            }
22470        }
22471
22472        app.curRawAdj = adj;
22473
22474        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
22475        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
22476        if (adj > app.maxAdj) {
22477            adj = app.maxAdj;
22478            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
22479                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22480            }
22481        }
22482
22483        // Do final modification to adj.  Everything we do between here and applying
22484        // the final setAdj must be done in this function, because we will also use
22485        // it when computing the final cached adj later.  Note that we don't need to
22486        // worry about this for max adj above, since max adj will always be used to
22487        // keep it out of the cached vaues.
22488        app.curAdj = app.modifyRawOomAdj(adj);
22489        app.curSchedGroup = schedGroup;
22490        app.curProcState = procState;
22491        app.foregroundActivities = foregroundActivities;
22492
22493        return app.curRawAdj;
22494    }
22495
22496    /**
22497     * Record new PSS sample for a process.
22498     */
22499    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
22500            long pssDuration, long now) {
22501        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
22502                swapPss * 1024);
22503        proc.lastPssTime = now;
22504        proc.baseProcessTracker.addPss(pss, uss, true, ProcessStats.ADD_PSS_INTERNAL,
22505                pssDuration, proc.pkgList);
22506        if (DEBUG_PSS) Slog.d(TAG_PSS,
22507                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
22508                + " state=" + ProcessList.makeProcStateString(procState));
22509        if (proc.initialIdlePss == 0) {
22510            proc.initialIdlePss = pss;
22511        }
22512        proc.lastPss = pss;
22513        proc.lastSwapPss = swapPss;
22514        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
22515            proc.lastCachedPss = pss;
22516            proc.lastCachedSwapPss = swapPss;
22517        }
22518
22519        final SparseArray<Pair<Long, String>> watchUids
22520                = mMemWatchProcesses.getMap().get(proc.processName);
22521        Long check = null;
22522        if (watchUids != null) {
22523            Pair<Long, String> val = watchUids.get(proc.uid);
22524            if (val == null) {
22525                val = watchUids.get(0);
22526            }
22527            if (val != null) {
22528                check = val.first;
22529            }
22530        }
22531        if (check != null) {
22532            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
22533                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22534                if (!isDebuggable) {
22535                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
22536                        isDebuggable = true;
22537                    }
22538                }
22539                if (isDebuggable) {
22540                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
22541                    final ProcessRecord myProc = proc;
22542                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
22543                    mMemWatchDumpProcName = proc.processName;
22544                    mMemWatchDumpFile = heapdumpFile.toString();
22545                    mMemWatchDumpPid = proc.pid;
22546                    mMemWatchDumpUid = proc.uid;
22547                    BackgroundThread.getHandler().post(new Runnable() {
22548                        @Override
22549                        public void run() {
22550                            revokeUriPermission(ActivityThread.currentActivityThread()
22551                                            .getApplicationThread(),
22552                                    null, DumpHeapActivity.JAVA_URI,
22553                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
22554                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
22555                                    UserHandle.myUserId());
22556                            ParcelFileDescriptor fd = null;
22557                            try {
22558                                heapdumpFile.delete();
22559                                fd = ParcelFileDescriptor.open(heapdumpFile,
22560                                        ParcelFileDescriptor.MODE_CREATE |
22561                                                ParcelFileDescriptor.MODE_TRUNCATE |
22562                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
22563                                                ParcelFileDescriptor.MODE_APPEND);
22564                                IApplicationThread thread = myProc.thread;
22565                                if (thread != null) {
22566                                    try {
22567                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
22568                                                "Requesting dump heap from "
22569                                                + myProc + " to " + heapdumpFile);
22570                                        thread.dumpHeap(/* managed= */ true,
22571                                                /* mallocInfo= */ false, /* runGc= */ false,
22572                                                heapdumpFile.toString(), fd);
22573                                    } catch (RemoteException e) {
22574                                    }
22575                                }
22576                            } catch (FileNotFoundException e) {
22577                                e.printStackTrace();
22578                            } finally {
22579                                if (fd != null) {
22580                                    try {
22581                                        fd.close();
22582                                    } catch (IOException e) {
22583                                    }
22584                                }
22585                            }
22586                        }
22587                    });
22588                } else {
22589                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
22590                            + ", but debugging not enabled");
22591                }
22592            }
22593        }
22594    }
22595
22596    /**
22597     * Schedule PSS collection of a process.
22598     */
22599    void requestPssLocked(ProcessRecord proc, int procState) {
22600        if (mPendingPssProcesses.contains(proc)) {
22601            return;
22602        }
22603        if (mPendingPssProcesses.size() == 0) {
22604            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
22605        }
22606        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
22607        proc.pssProcState = procState;
22608        mPendingPssProcesses.add(proc);
22609    }
22610
22611    /**
22612     * Schedule PSS collection of all processes.
22613     */
22614    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
22615        if (!always) {
22616            if (now < (mLastFullPssTime +
22617                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
22618                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
22619                return;
22620            }
22621        }
22622        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
22623        mLastFullPssTime = now;
22624        mFullPssPending = true;
22625        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
22626        mPendingPssProcesses.clear();
22627        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22628            ProcessRecord app = mLruProcesses.get(i);
22629            if (app.thread == null
22630                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22631                continue;
22632            }
22633            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
22634                app.pssProcState = app.setProcState;
22635                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22636                        mTestPssMode, isSleepingLocked(), now);
22637                mPendingPssProcesses.add(app);
22638            }
22639        }
22640        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
22641    }
22642
22643    public void setTestPssMode(boolean enabled) {
22644        synchronized (this) {
22645            mTestPssMode = enabled;
22646            if (enabled) {
22647                // Whenever we enable the mode, we want to take a snapshot all of current
22648                // process mem use.
22649                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
22650            }
22651        }
22652    }
22653
22654    /**
22655     * Ask a given process to GC right now.
22656     */
22657    final void performAppGcLocked(ProcessRecord app) {
22658        try {
22659            app.lastRequestedGc = SystemClock.uptimeMillis();
22660            if (app.thread != null) {
22661                if (app.reportLowMemory) {
22662                    app.reportLowMemory = false;
22663                    app.thread.scheduleLowMemory();
22664                } else {
22665                    app.thread.processInBackground();
22666                }
22667            }
22668        } catch (Exception e) {
22669            // whatever.
22670        }
22671    }
22672
22673    /**
22674     * Returns true if things are idle enough to perform GCs.
22675     */
22676    private final boolean canGcNowLocked() {
22677        boolean processingBroadcasts = false;
22678        for (BroadcastQueue q : mBroadcastQueues) {
22679            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
22680                processingBroadcasts = true;
22681            }
22682        }
22683        return !processingBroadcasts
22684                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
22685    }
22686
22687    /**
22688     * Perform GCs on all processes that are waiting for it, but only
22689     * if things are idle.
22690     */
22691    final void performAppGcsLocked() {
22692        final int N = mProcessesToGc.size();
22693        if (N <= 0) {
22694            return;
22695        }
22696        if (canGcNowLocked()) {
22697            while (mProcessesToGc.size() > 0) {
22698                ProcessRecord proc = mProcessesToGc.remove(0);
22699                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
22700                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
22701                            <= SystemClock.uptimeMillis()) {
22702                        // To avoid spamming the system, we will GC processes one
22703                        // at a time, waiting a few seconds between each.
22704                        performAppGcLocked(proc);
22705                        scheduleAppGcsLocked();
22706                        return;
22707                    } else {
22708                        // It hasn't been long enough since we last GCed this
22709                        // process...  put it in the list to wait for its time.
22710                        addProcessToGcListLocked(proc);
22711                        break;
22712                    }
22713                }
22714            }
22715
22716            scheduleAppGcsLocked();
22717        }
22718    }
22719
22720    /**
22721     * If all looks good, perform GCs on all processes waiting for them.
22722     */
22723    final void performAppGcsIfAppropriateLocked() {
22724        if (canGcNowLocked()) {
22725            performAppGcsLocked();
22726            return;
22727        }
22728        // Still not idle, wait some more.
22729        scheduleAppGcsLocked();
22730    }
22731
22732    /**
22733     * Schedule the execution of all pending app GCs.
22734     */
22735    final void scheduleAppGcsLocked() {
22736        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
22737
22738        if (mProcessesToGc.size() > 0) {
22739            // Schedule a GC for the time to the next process.
22740            ProcessRecord proc = mProcessesToGc.get(0);
22741            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
22742
22743            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
22744            long now = SystemClock.uptimeMillis();
22745            if (when < (now+mConstants.GC_TIMEOUT)) {
22746                when = now + mConstants.GC_TIMEOUT;
22747            }
22748            mHandler.sendMessageAtTime(msg, when);
22749        }
22750    }
22751
22752    /**
22753     * Add a process to the array of processes waiting to be GCed.  Keeps the
22754     * list in sorted order by the last GC time.  The process can't already be
22755     * on the list.
22756     */
22757    final void addProcessToGcListLocked(ProcessRecord proc) {
22758        boolean added = false;
22759        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
22760            if (mProcessesToGc.get(i).lastRequestedGc <
22761                    proc.lastRequestedGc) {
22762                added = true;
22763                mProcessesToGc.add(i+1, proc);
22764                break;
22765            }
22766        }
22767        if (!added) {
22768            mProcessesToGc.add(0, proc);
22769        }
22770    }
22771
22772    /**
22773     * Set up to ask a process to GC itself.  This will either do it
22774     * immediately, or put it on the list of processes to gc the next
22775     * time things are idle.
22776     */
22777    final void scheduleAppGcLocked(ProcessRecord app) {
22778        long now = SystemClock.uptimeMillis();
22779        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
22780            return;
22781        }
22782        if (!mProcessesToGc.contains(app)) {
22783            addProcessToGcListLocked(app);
22784            scheduleAppGcsLocked();
22785        }
22786    }
22787
22788    final void checkExcessivePowerUsageLocked() {
22789        updateCpuStatsNow();
22790
22791        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
22792        boolean doCpuKills = true;
22793        if (mLastPowerCheckUptime == 0) {
22794            doCpuKills = false;
22795        }
22796        final long curUptime = SystemClock.uptimeMillis();
22797        final long uptimeSince = curUptime - mLastPowerCheckUptime;
22798        mLastPowerCheckUptime = curUptime;
22799        int i = mLruProcesses.size();
22800        while (i > 0) {
22801            i--;
22802            ProcessRecord app = mLruProcesses.get(i);
22803            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22804                if (app.lastCpuTime <= 0) {
22805                    continue;
22806                }
22807                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
22808                if (DEBUG_POWER) {
22809                    StringBuilder sb = new StringBuilder(128);
22810                    sb.append("CPU for ");
22811                    app.toShortString(sb);
22812                    sb.append(": over ");
22813                    TimeUtils.formatDuration(uptimeSince, sb);
22814                    sb.append(" used ");
22815                    TimeUtils.formatDuration(cputimeUsed, sb);
22816                    sb.append(" (");
22817                    sb.append((cputimeUsed*100)/uptimeSince);
22818                    sb.append("%)");
22819                    Slog.i(TAG_POWER, sb.toString());
22820                }
22821                // If the process has used too much CPU over the last duration, the
22822                // user probably doesn't want this, so kill!
22823                if (doCpuKills && uptimeSince > 0) {
22824                    // What is the limit for this process?
22825                    int cpuLimit;
22826                    long checkDur = curUptime - app.whenUnimportant;
22827                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
22828                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
22829                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
22830                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
22831                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
22832                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
22833                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
22834                    } else {
22835                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
22836                    }
22837                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
22838                        synchronized (stats) {
22839                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
22840                                    uptimeSince, cputimeUsed);
22841                        }
22842                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
22843                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
22844                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
22845                    }
22846                }
22847                app.lastCpuTime = app.curCpuTime;
22848            }
22849        }
22850    }
22851
22852    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22853            long nowElapsed) {
22854        boolean success = true;
22855
22856        if (app.curRawAdj != app.setRawAdj) {
22857            app.setRawAdj = app.curRawAdj;
22858        }
22859
22860        int changes = 0;
22861
22862        if (app.curAdj != app.setAdj) {
22863            ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22864            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22865                String msg = "Set " + app.pid + " " + app.processName + " adj "
22866                        + app.curAdj + ": " + app.adjType;
22867                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22868            }
22869            app.setAdj = app.curAdj;
22870            app.verifiedAdj = ProcessList.INVALID_ADJ;
22871        }
22872
22873        if (app.setSchedGroup != app.curSchedGroup) {
22874            int oldSchedGroup = app.setSchedGroup;
22875            app.setSchedGroup = app.curSchedGroup;
22876            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22877                String msg = "Setting sched group of " + app.processName
22878                        + " to " + app.curSchedGroup;
22879                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22880            }
22881            if (app.waitingToKill != null && app.curReceivers.isEmpty()
22882                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22883                app.kill(app.waitingToKill, true);
22884                success = false;
22885            } else {
22886                int processGroup;
22887                switch (app.curSchedGroup) {
22888                    case ProcessList.SCHED_GROUP_BACKGROUND:
22889                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22890                        break;
22891                    case ProcessList.SCHED_GROUP_TOP_APP:
22892                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22893                        processGroup = THREAD_GROUP_TOP_APP;
22894                        break;
22895                    default:
22896                        processGroup = THREAD_GROUP_DEFAULT;
22897                        break;
22898                }
22899                long oldId = Binder.clearCallingIdentity();
22900                try {
22901                    setProcessGroup(app.pid, processGroup);
22902                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22903                        // do nothing if we already switched to RT
22904                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22905                            mVrController.onTopProcChangedLocked(app);
22906                            if (mUseFifoUiScheduling) {
22907                                // Switch UI pipeline for app to SCHED_FIFO
22908                                app.savedPriority = Process.getThreadPriority(app.pid);
22909                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22910                                if (app.renderThreadTid != 0) {
22911                                    scheduleAsFifoPriority(app.renderThreadTid,
22912                                        /* suppressLogs */true);
22913                                    if (DEBUG_OOM_ADJ) {
22914                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
22915                                            app.renderThreadTid + ") to FIFO");
22916                                    }
22917                                } else {
22918                                    if (DEBUG_OOM_ADJ) {
22919                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
22920                                    }
22921                                }
22922                            } else {
22923                                // Boost priority for top app UI and render threads
22924                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22925                                if (app.renderThreadTid != 0) {
22926                                    try {
22927                                        setThreadPriority(app.renderThreadTid,
22928                                                TOP_APP_PRIORITY_BOOST);
22929                                    } catch (IllegalArgumentException e) {
22930                                        // thread died, ignore
22931                                    }
22932                                }
22933                            }
22934                        }
22935                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22936                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22937                        mVrController.onTopProcChangedLocked(app);
22938                        if (mUseFifoUiScheduling) {
22939                            try {
22940                                // Reset UI pipeline to SCHED_OTHER
22941                                setThreadScheduler(app.pid, SCHED_OTHER, 0);
22942                                setThreadPriority(app.pid, app.savedPriority);
22943                                if (app.renderThreadTid != 0) {
22944                                    setThreadScheduler(app.renderThreadTid,
22945                                        SCHED_OTHER, 0);
22946                                    setThreadPriority(app.renderThreadTid, -4);
22947                                }
22948                            } catch (IllegalArgumentException e) {
22949                                Slog.w(TAG,
22950                                        "Failed to set scheduling policy, thread does not exist:\n"
22951                                                + e);
22952                            } catch (SecurityException e) {
22953                                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22954                            }
22955                        } else {
22956                            // Reset priority for top app UI and render threads
22957                            setThreadPriority(app.pid, 0);
22958                            if (app.renderThreadTid != 0) {
22959                                setThreadPriority(app.renderThreadTid, 0);
22960                            }
22961                        }
22962                    }
22963                } catch (Exception e) {
22964                    if (false) {
22965                        Slog.w(TAG, "Failed setting process group of " + app.pid
22966                                + " to " + app.curSchedGroup);
22967                        Slog.w(TAG, "at location", e);
22968                    }
22969                } finally {
22970                    Binder.restoreCallingIdentity(oldId);
22971                }
22972            }
22973        }
22974        if (app.repForegroundActivities != app.foregroundActivities) {
22975            app.repForegroundActivities = app.foregroundActivities;
22976            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22977        }
22978        if (app.repProcState != app.curProcState) {
22979            app.repProcState = app.curProcState;
22980            if (app.thread != null) {
22981                try {
22982                    if (false) {
22983                        //RuntimeException h = new RuntimeException("here");
22984                        Slog.i(TAG, "Sending new process state " + app.repProcState
22985                                + " to " + app /*, h*/);
22986                    }
22987                    app.thread.setProcessState(app.repProcState);
22988                } catch (RemoteException e) {
22989                }
22990            }
22991        }
22992        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22993                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22994            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22995                // Experimental code to more aggressively collect pss while
22996                // running test...  the problem is that this tends to collect
22997                // the data right when a process is transitioning between process
22998                // states, which well tend to give noisy data.
22999                long start = SystemClock.uptimeMillis();
23000                long startTime = SystemClock.currentThreadTimeMillis();
23001                long pss = Debug.getPss(app.pid, mTmpLong, null);
23002                long endTime = SystemClock.currentThreadTimeMillis();
23003                recordPssSampleLocked(app, app.curProcState, pss, endTime-startTime,
23004                        mTmpLong[0], mTmpLong[1], now);
23005                mPendingPssProcesses.remove(app);
23006                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
23007                        + " to " + app.curProcState + ": "
23008                        + (SystemClock.uptimeMillis()-start) + "ms");
23009            }
23010            app.lastStateTime = now;
23011            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
23012                    mTestPssMode, isSleepingLocked(), now);
23013            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
23014                    + ProcessList.makeProcStateString(app.setProcState) + " to "
23015                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
23016                    + (app.nextPssTime-now) + ": " + app);
23017        } else {
23018            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
23019                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
23020                    mTestPssMode)))) {
23021                requestPssLocked(app, app.setProcState);
23022                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
23023                        mTestPssMode, isSleepingLocked(), now);
23024            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
23025                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
23026        }
23027        if (app.setProcState != app.curProcState) {
23028            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
23029                String msg = "Proc state change of " + app.processName
23030                        + " to " + app.curProcState;
23031                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23032            }
23033            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
23034            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
23035            if (setImportant && !curImportant) {
23036                // This app is no longer something we consider important enough to allow to
23037                // use arbitrary amounts of battery power.  Note
23038                // its current CPU time to later know to kill it if
23039                // it is not behaving well.
23040                app.whenUnimportant = now;
23041                app.lastCpuTime = 0;
23042            }
23043            // Inform UsageStats of important process state change
23044            // Must be called before updating setProcState
23045            maybeUpdateUsageStatsLocked(app, nowElapsed);
23046
23047            app.setProcState = app.curProcState;
23048            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
23049                app.notCachedSinceIdle = false;
23050            }
23051            if (!doingAll) {
23052                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
23053            } else {
23054                app.procStateChanged = true;
23055            }
23056        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
23057                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
23058            // For apps that sit around for a long time in the interactive state, we need
23059            // to report this at least once a day so they don't go idle.
23060            maybeUpdateUsageStatsLocked(app, nowElapsed);
23061        }
23062
23063        if (changes != 0) {
23064            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23065                    "Changes in " + app + ": " + changes);
23066            int i = mPendingProcessChanges.size()-1;
23067            ProcessChangeItem item = null;
23068            while (i >= 0) {
23069                item = mPendingProcessChanges.get(i);
23070                if (item.pid == app.pid) {
23071                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23072                            "Re-using existing item: " + item);
23073                    break;
23074                }
23075                i--;
23076            }
23077            if (i < 0) {
23078                // No existing item in pending changes; need a new one.
23079                final int NA = mAvailProcessChanges.size();
23080                if (NA > 0) {
23081                    item = mAvailProcessChanges.remove(NA-1);
23082                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23083                            "Retrieving available item: " + item);
23084                } else {
23085                    item = new ProcessChangeItem();
23086                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23087                            "Allocating new item: " + item);
23088                }
23089                item.changes = 0;
23090                item.pid = app.pid;
23091                item.uid = app.info.uid;
23092                if (mPendingProcessChanges.size() == 0) {
23093                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23094                            "*** Enqueueing dispatch processes changed!");
23095                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
23096                }
23097                mPendingProcessChanges.add(item);
23098            }
23099            item.changes |= changes;
23100            item.foregroundActivities = app.repForegroundActivities;
23101            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
23102                    "Item " + Integer.toHexString(System.identityHashCode(item))
23103                    + " " + app.toShortString() + ": changes=" + item.changes
23104                    + " foreground=" + item.foregroundActivities
23105                    + " type=" + app.adjType + " source=" + app.adjSource
23106                    + " target=" + app.adjTarget);
23107        }
23108
23109        return success;
23110    }
23111
23112    private boolean isEphemeralLocked(int uid) {
23113        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
23114        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
23115            return false;
23116        }
23117        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
23118                packages[0]);
23119    }
23120
23121    @VisibleForTesting
23122    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
23123        final UidRecord.ChangeItem pendingChange;
23124        if (uidRec == null || uidRec.pendingChange == null) {
23125            if (mPendingUidChanges.size() == 0) {
23126                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23127                        "*** Enqueueing dispatch uid changed!");
23128                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
23129            }
23130            final int NA = mAvailUidChanges.size();
23131            if (NA > 0) {
23132                pendingChange = mAvailUidChanges.remove(NA-1);
23133                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23134                        "Retrieving available item: " + pendingChange);
23135            } else {
23136                pendingChange = new UidRecord.ChangeItem();
23137                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23138                        "Allocating new item: " + pendingChange);
23139            }
23140            if (uidRec != null) {
23141                uidRec.pendingChange = pendingChange;
23142                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
23143                    // If this uid is going away, and we haven't yet reported it is gone,
23144                    // then do so now.
23145                    change |= UidRecord.CHANGE_IDLE;
23146                }
23147            } else if (uid < 0) {
23148                throw new IllegalArgumentException("No UidRecord or uid");
23149            }
23150            pendingChange.uidRecord = uidRec;
23151            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
23152            mPendingUidChanges.add(pendingChange);
23153        } else {
23154            pendingChange = uidRec.pendingChange;
23155            // If there is no change in idle or active state, then keep whatever was pending.
23156            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
23157                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
23158                        | UidRecord.CHANGE_ACTIVE));
23159            }
23160            // If there is no change in cached or uncached state, then keep whatever was pending.
23161            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
23162                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
23163                        | UidRecord.CHANGE_UNCACHED));
23164            }
23165            // If this is a report of the UID being gone, then we shouldn't keep any previous
23166            // report of it being active or cached.  (That is, a gone uid is never active,
23167            // and never cached.)
23168            if ((change & UidRecord.CHANGE_GONE) != 0) {
23169                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
23170                if (!uidRec.idle) {
23171                    // If this uid is going away, and we haven't yet reported it is gone,
23172                    // then do so now.
23173                    change |= UidRecord.CHANGE_IDLE;
23174                }
23175            }
23176        }
23177        pendingChange.change = change;
23178        pendingChange.processState = uidRec != null
23179                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
23180        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
23181        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
23182        if (uidRec != null) {
23183            uidRec.lastReportedChange = change;
23184            uidRec.updateLastDispatchedProcStateSeq(change);
23185        }
23186
23187        // Directly update the power manager, since we sit on top of it and it is critical
23188        // it be kept in sync (so wake locks will be held as soon as appropriate).
23189        if (mLocalPowerManager != null) {
23190            // TO DO: dispatch cached/uncached changes here, so we don't need to report
23191            // all proc state changes.
23192            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
23193                mLocalPowerManager.uidActive(pendingChange.uid);
23194            }
23195            if ((change & UidRecord.CHANGE_IDLE) != 0) {
23196                mLocalPowerManager.uidIdle(pendingChange.uid);
23197            }
23198            if ((change & UidRecord.CHANGE_GONE) != 0) {
23199                mLocalPowerManager.uidGone(pendingChange.uid);
23200            } else {
23201                mLocalPowerManager.updateUidProcState(pendingChange.uid,
23202                        pendingChange.processState);
23203            }
23204        }
23205    }
23206
23207    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
23208            String authority) {
23209        if (app == null) return;
23210        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23211            UserState userState = mUserController.getStartedUserState(app.userId);
23212            if (userState == null) return;
23213            final long now = SystemClock.elapsedRealtime();
23214            Long lastReported = userState.mProviderLastReportedFg.get(authority);
23215            if (lastReported == null || lastReported < now - 60 * 1000L) {
23216                if (mSystemReady) {
23217                    // Cannot touch the user stats if not system ready
23218                    mUsageStatsService.reportContentProviderUsage(
23219                            authority, providerPkgName, app.userId);
23220                }
23221                userState.mProviderLastReportedFg.put(authority, now);
23222            }
23223        }
23224    }
23225
23226    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
23227        if (DEBUG_USAGE_STATS) {
23228            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
23229                    + "] state changes: old = " + app.setProcState + ", new = "
23230                    + app.curProcState);
23231        }
23232        if (mUsageStatsService == null) {
23233            return;
23234        }
23235        boolean isInteraction;
23236        // To avoid some abuse patterns, we are going to be careful about what we consider
23237        // to be an app interaction.  Being the top activity doesn't count while the display
23238        // is sleeping, nor do short foreground services.
23239        if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
23240            isInteraction = true;
23241            app.fgInteractionTime = 0;
23242        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
23243            if (app.fgInteractionTime == 0) {
23244                app.fgInteractionTime = nowElapsed;
23245                isInteraction = false;
23246            } else {
23247                isInteraction = nowElapsed > app.fgInteractionTime
23248                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
23249            }
23250        } else {
23251            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23252            app.fgInteractionTime = 0;
23253        }
23254        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
23255                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
23256            app.interactionEventTime = nowElapsed;
23257            String[] packages = app.getPackageList();
23258            if (packages != null) {
23259                for (int i = 0; i < packages.length; i++) {
23260                    mUsageStatsService.reportEvent(packages[i], app.userId,
23261                            UsageEvents.Event.SYSTEM_INTERACTION);
23262                }
23263            }
23264        }
23265        app.reportedInteraction = isInteraction;
23266        if (!isInteraction) {
23267            app.interactionEventTime = 0;
23268        }
23269    }
23270
23271    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
23272        if (proc.thread != null) {
23273            if (proc.baseProcessTracker != null) {
23274                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
23275            }
23276        }
23277    }
23278
23279    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
23280            ProcessRecord TOP_APP, boolean doingAll, long now) {
23281        if (app.thread == null) {
23282            return false;
23283        }
23284
23285        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
23286
23287        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
23288    }
23289
23290    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
23291            boolean oomAdj) {
23292        if (isForeground != proc.foregroundServices) {
23293            proc.foregroundServices = isForeground;
23294            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
23295                    proc.info.uid);
23296            if (isForeground) {
23297                if (curProcs == null) {
23298                    curProcs = new ArrayList<ProcessRecord>();
23299                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
23300                }
23301                if (!curProcs.contains(proc)) {
23302                    curProcs.add(proc);
23303                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
23304                            proc.info.packageName, proc.info.uid);
23305                }
23306            } else {
23307                if (curProcs != null) {
23308                    if (curProcs.remove(proc)) {
23309                        mBatteryStatsService.noteEvent(
23310                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
23311                                proc.info.packageName, proc.info.uid);
23312                        if (curProcs.size() <= 0) {
23313                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
23314                        }
23315                    }
23316                }
23317            }
23318            if (oomAdj) {
23319                updateOomAdjLocked();
23320            }
23321        }
23322    }
23323
23324    private final ActivityRecord resumedAppLocked() {
23325        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
23326        String pkg;
23327        int uid;
23328        if (act != null) {
23329            pkg = act.packageName;
23330            uid = act.info.applicationInfo.uid;
23331        } else {
23332            pkg = null;
23333            uid = -1;
23334        }
23335        // Has the UID or resumed package name changed?
23336        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
23337                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
23338            if (mCurResumedPackage != null) {
23339                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
23340                        mCurResumedPackage, mCurResumedUid);
23341            }
23342            mCurResumedPackage = pkg;
23343            mCurResumedUid = uid;
23344            if (mCurResumedPackage != null) {
23345                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
23346                        mCurResumedPackage, mCurResumedUid);
23347            }
23348        }
23349        return act;
23350    }
23351
23352    /**
23353     * Update OomAdj for a specific process.
23354     * @param app The process to update
23355     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
23356     *                  if necessary, or skip.
23357     * @return whether updateOomAdjLocked(app) was successful.
23358     */
23359    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
23360        final ActivityRecord TOP_ACT = resumedAppLocked();
23361        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
23362        final boolean wasCached = app.cached;
23363
23364        mAdjSeq++;
23365
23366        // This is the desired cached adjusment we want to tell it to use.
23367        // If our app is currently cached, we know it, and that is it.  Otherwise,
23368        // we don't know it yet, and it needs to now be cached we will then
23369        // need to do a complete oom adj.
23370        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
23371                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
23372        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
23373                SystemClock.uptimeMillis());
23374        if (oomAdjAll
23375                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
23376            // Changed to/from cached state, so apps after it in the LRU
23377            // list may also be changed.
23378            updateOomAdjLocked();
23379        }
23380        return success;
23381    }
23382
23383    final void updateOomAdjLocked() {
23384        final ActivityRecord TOP_ACT = resumedAppLocked();
23385        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
23386        final long now = SystemClock.uptimeMillis();
23387        final long nowElapsed = SystemClock.elapsedRealtime();
23388        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
23389        final int N = mLruProcesses.size();
23390
23391        if (false) {
23392            RuntimeException e = new RuntimeException();
23393            e.fillInStackTrace();
23394            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
23395        }
23396
23397        // Reset state in all uid records.
23398        for (int i=mActiveUids.size()-1; i>=0; i--) {
23399            final UidRecord uidRec = mActiveUids.valueAt(i);
23400            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23401                    "Starting update of " + uidRec);
23402            uidRec.reset();
23403        }
23404
23405        mStackSupervisor.rankTaskLayersIfNeeded();
23406
23407        mAdjSeq++;
23408        mNewNumServiceProcs = 0;
23409        mNewNumAServiceProcs = 0;
23410
23411        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
23412        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
23413
23414        // Let's determine how many processes we have running vs.
23415        // how many slots we have for background processes; we may want
23416        // to put multiple processes in a slot of there are enough of
23417        // them.
23418        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
23419                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
23420        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
23421        if (numEmptyProcs > cachedProcessLimit) {
23422            // If there are more empty processes than our limit on cached
23423            // processes, then use the cached process limit for the factor.
23424            // This ensures that the really old empty processes get pushed
23425            // down to the bottom, so if we are running low on memory we will
23426            // have a better chance at keeping around more cached processes
23427            // instead of a gazillion empty processes.
23428            numEmptyProcs = cachedProcessLimit;
23429        }
23430        int emptyFactor = numEmptyProcs/numSlots;
23431        if (emptyFactor < 1) emptyFactor = 1;
23432        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
23433        if (cachedFactor < 1) cachedFactor = 1;
23434        int stepCached = 0;
23435        int stepEmpty = 0;
23436        int numCached = 0;
23437        int numEmpty = 0;
23438        int numTrimming = 0;
23439
23440        mNumNonCachedProcs = 0;
23441        mNumCachedHiddenProcs = 0;
23442
23443        // First update the OOM adjustment for each of the
23444        // application processes based on their current state.
23445        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
23446        int nextCachedAdj = curCachedAdj+1;
23447        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
23448        int nextEmptyAdj = curEmptyAdj+2;
23449        for (int i=N-1; i>=0; i--) {
23450            ProcessRecord app = mLruProcesses.get(i);
23451            if (!app.killedByAm && app.thread != null) {
23452                app.procStateChanged = false;
23453                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
23454
23455                // If we haven't yet assigned the final cached adj
23456                // to the process, do that now.
23457                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
23458                    switch (app.curProcState) {
23459                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
23460                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
23461                        case ActivityManager.PROCESS_STATE_CACHED_RECENT:
23462                            // This process is a cached process holding activities...
23463                            // assign it the next cached value for that type, and then
23464                            // step that cached level.
23465                            app.curRawAdj = curCachedAdj;
23466                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
23467                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
23468                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
23469                                    + ")");
23470                            if (curCachedAdj != nextCachedAdj) {
23471                                stepCached++;
23472                                if (stepCached >= cachedFactor) {
23473                                    stepCached = 0;
23474                                    curCachedAdj = nextCachedAdj;
23475                                    nextCachedAdj += 2;
23476                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
23477                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
23478                                    }
23479                                }
23480                            }
23481                            break;
23482                        default:
23483                            // For everything else, assign next empty cached process
23484                            // level and bump that up.  Note that this means that
23485                            // long-running services that have dropped down to the
23486                            // cached level will be treated as empty (since their process
23487                            // state is still as a service), which is what we want.
23488                            app.curRawAdj = curEmptyAdj;
23489                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
23490                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
23491                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
23492                                    + ")");
23493                            if (curEmptyAdj != nextEmptyAdj) {
23494                                stepEmpty++;
23495                                if (stepEmpty >= emptyFactor) {
23496                                    stepEmpty = 0;
23497                                    curEmptyAdj = nextEmptyAdj;
23498                                    nextEmptyAdj += 2;
23499                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
23500                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
23501                                    }
23502                                }
23503                            }
23504                            break;
23505                    }
23506                }
23507
23508                applyOomAdjLocked(app, true, now, nowElapsed);
23509
23510                // Count the number of process types.
23511                switch (app.curProcState) {
23512                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
23513                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
23514                        mNumCachedHiddenProcs++;
23515                        numCached++;
23516                        if (numCached > cachedProcessLimit) {
23517                            app.kill("cached #" + numCached, true);
23518                        }
23519                        break;
23520                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
23521                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
23522                                && app.lastActivityTime < oldTime) {
23523                            app.kill("empty for "
23524                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
23525                                    / 1000) + "s", true);
23526                        } else {
23527                            numEmpty++;
23528                            if (numEmpty > emptyProcessLimit) {
23529                                app.kill("empty #" + numEmpty, true);
23530                            }
23531                        }
23532                        break;
23533                    default:
23534                        mNumNonCachedProcs++;
23535                        break;
23536                }
23537
23538                if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
23539                    // If this is an isolated process, there are no services
23540                    // running in it, and it's not a special process with a
23541                    // custom entry point, then the process is no longer
23542                    // needed.  We agressively kill these because we can by
23543                    // definition not re-use the same process again, and it is
23544                    // good to avoid having whatever code was running in them
23545                    // left sitting around after no longer needed.
23546                    app.kill("isolated not needed", true);
23547                } else {
23548                    // Keeping this process, update its uid.
23549                    final UidRecord uidRec = app.uidRecord;
23550                    if (uidRec != null) {
23551                        uidRec.ephemeral = app.info.isInstantApp();
23552                        if (uidRec.curProcState > app.curProcState) {
23553                            uidRec.curProcState = app.curProcState;
23554                        }
23555                        if (app.foregroundServices) {
23556                            uidRec.foregroundServices = true;
23557                        }
23558                    }
23559                }
23560
23561                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
23562                        && !app.killedByAm) {
23563                    numTrimming++;
23564                }
23565            }
23566        }
23567
23568        incrementProcStateSeqAndNotifyAppsLocked();
23569
23570        mNumServiceProcs = mNewNumServiceProcs;
23571
23572        // Now determine the memory trimming level of background processes.
23573        // Unfortunately we need to start at the back of the list to do this
23574        // properly.  We only do this if the number of background apps we
23575        // are managing to keep around is less than half the maximum we desire;
23576        // if we are keeping a good number around, we'll let them use whatever
23577        // memory they want.
23578        final int numCachedAndEmpty = numCached + numEmpty;
23579        int memFactor;
23580        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
23581                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
23582            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
23583                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
23584            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
23585                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
23586            } else {
23587                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
23588            }
23589        } else {
23590            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
23591        }
23592        // We always allow the memory level to go up (better).  We only allow it to go
23593        // down if we are in a state where that is allowed, *and* the total number of processes
23594        // has gone down since last time.
23595        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
23596                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
23597                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
23598        if (memFactor > mLastMemoryLevel) {
23599            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
23600                memFactor = mLastMemoryLevel;
23601                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
23602            }
23603        }
23604        if (memFactor != mLastMemoryLevel) {
23605            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
23606        }
23607        mLastMemoryLevel = memFactor;
23608        mLastNumProcesses = mLruProcesses.size();
23609        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
23610        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
23611        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
23612            if (mLowRamStartTime == 0) {
23613                mLowRamStartTime = now;
23614            }
23615            int step = 0;
23616            int fgTrimLevel;
23617            switch (memFactor) {
23618                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
23619                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
23620                    break;
23621                case ProcessStats.ADJ_MEM_FACTOR_LOW:
23622                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
23623                    break;
23624                default:
23625                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
23626                    break;
23627            }
23628            int factor = numTrimming/3;
23629            int minFactor = 2;
23630            if (mHomeProcess != null) minFactor++;
23631            if (mPreviousProcess != null) minFactor++;
23632            if (factor < minFactor) factor = minFactor;
23633            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
23634            for (int i=N-1; i>=0; i--) {
23635                ProcessRecord app = mLruProcesses.get(i);
23636                if (allChanged || app.procStateChanged) {
23637                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
23638                    app.procStateChanged = false;
23639                }
23640                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
23641                        && !app.killedByAm) {
23642                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
23643                        try {
23644                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
23645                                    "Trimming memory of " + app.processName + " to " + curLevel);
23646                            app.thread.scheduleTrimMemory(curLevel);
23647                        } catch (RemoteException e) {
23648                        }
23649                        if (false) {
23650                            // For now we won't do this; our memory trimming seems
23651                            // to be good enough at this point that destroying
23652                            // activities causes more harm than good.
23653                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
23654                                    && app != mHomeProcess && app != mPreviousProcess) {
23655                                // Need to do this on its own message because the stack may not
23656                                // be in a consistent state at this point.
23657                                // For these apps we will also finish their activities
23658                                // to help them free memory.
23659                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
23660                            }
23661                        }
23662                    }
23663                    app.trimMemoryLevel = curLevel;
23664                    step++;
23665                    if (step >= factor) {
23666                        step = 0;
23667                        switch (curLevel) {
23668                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
23669                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
23670                                break;
23671                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
23672                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
23673                                break;
23674                        }
23675                    }
23676                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
23677                        && !app.killedByAm) {
23678                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
23679                            && app.thread != null) {
23680                        try {
23681                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
23682                                    "Trimming memory of heavy-weight " + app.processName
23683                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
23684                            app.thread.scheduleTrimMemory(
23685                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
23686                        } catch (RemoteException e) {
23687                        }
23688                    }
23689                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
23690                } else {
23691                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
23692                            || app.systemNoUi) && app.pendingUiClean) {
23693                        // If this application is now in the background and it
23694                        // had done UI, then give it the special trim level to
23695                        // have it free UI resources.
23696                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
23697                        if (app.trimMemoryLevel < level && app.thread != null) {
23698                            try {
23699                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
23700                                        "Trimming memory of bg-ui " + app.processName
23701                                        + " to " + level);
23702                                app.thread.scheduleTrimMemory(level);
23703                            } catch (RemoteException e) {
23704                            }
23705                        }
23706                        app.pendingUiClean = false;
23707                    }
23708                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
23709                        try {
23710                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
23711                                    "Trimming memory of fg " + app.processName
23712                                    + " to " + fgTrimLevel);
23713                            app.thread.scheduleTrimMemory(fgTrimLevel);
23714                        } catch (RemoteException e) {
23715                        }
23716                    }
23717                    app.trimMemoryLevel = fgTrimLevel;
23718                }
23719            }
23720        } else {
23721            if (mLowRamStartTime != 0) {
23722                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
23723                mLowRamStartTime = 0;
23724            }
23725            for (int i=N-1; i>=0; i--) {
23726                ProcessRecord app = mLruProcesses.get(i);
23727                if (allChanged || app.procStateChanged) {
23728                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
23729                    app.procStateChanged = false;
23730                }
23731                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
23732                        || app.systemNoUi) && app.pendingUiClean) {
23733                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
23734                            && app.thread != null) {
23735                        try {
23736                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
23737                                    "Trimming memory of ui hidden " + app.processName
23738                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
23739                            app.thread.scheduleTrimMemory(
23740                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
23741                        } catch (RemoteException e) {
23742                        }
23743                    }
23744                    app.pendingUiClean = false;
23745                }
23746                app.trimMemoryLevel = 0;
23747            }
23748        }
23749
23750        if (mAlwaysFinishActivities) {
23751            // Need to do this on its own message because the stack may not
23752            // be in a consistent state at this point.
23753            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
23754        }
23755
23756        if (allChanged) {
23757            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
23758        }
23759
23760        ArrayList<UidRecord> becameIdle = null;
23761
23762        // Update from any uid changes.
23763        if (mLocalPowerManager != null) {
23764            mLocalPowerManager.startUidChanges();
23765        }
23766        for (int i=mActiveUids.size()-1; i>=0; i--) {
23767            final UidRecord uidRec = mActiveUids.valueAt(i);
23768            int uidChange = UidRecord.CHANGE_PROCSTATE;
23769            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
23770                    && (uidRec.setProcState != uidRec.curProcState
23771                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
23772                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
23773                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
23774                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
23775                        + " to " + uidRec.curWhitelist);
23776                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
23777                        && !uidRec.curWhitelist) {
23778                    // UID is now in the background (and not on the temp whitelist).  Was it
23779                    // previously in the foreground (or on the temp whitelist)?
23780                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
23781                            || uidRec.setWhitelist) {
23782                        uidRec.lastBackgroundTime = nowElapsed;
23783                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
23784                            // Note: the background settle time is in elapsed realtime, while
23785                            // the handler time base is uptime.  All this means is that we may
23786                            // stop background uids later than we had intended, but that only
23787                            // happens because the device was sleeping so we are okay anyway.
23788                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23789                                    mConstants.BACKGROUND_SETTLE_TIME);
23790                        }
23791                    }
23792                    if (uidRec.idle && !uidRec.setIdle) {
23793                        uidChange = UidRecord.CHANGE_IDLE;
23794                        if (becameIdle == null) {
23795                            becameIdle = new ArrayList<>();
23796                        }
23797                        becameIdle.add(uidRec);
23798                    }
23799                } else {
23800                    if (uidRec.idle) {
23801                        uidChange = UidRecord.CHANGE_ACTIVE;
23802                        EventLogTags.writeAmUidActive(uidRec.uid);
23803                        uidRec.idle = false;
23804                    }
23805                    uidRec.lastBackgroundTime = 0;
23806                }
23807                final boolean wasCached = uidRec.setProcState
23808                        > ActivityManager.PROCESS_STATE_RECEIVER;
23809                final boolean isCached = uidRec.curProcState
23810                        > ActivityManager.PROCESS_STATE_RECEIVER;
23811                if (wasCached != isCached ||
23812                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
23813                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
23814                }
23815                uidRec.setProcState = uidRec.curProcState;
23816                uidRec.setWhitelist = uidRec.curWhitelist;
23817                uidRec.setIdle = uidRec.idle;
23818                enqueueUidChangeLocked(uidRec, -1, uidChange);
23819                noteUidProcessState(uidRec.uid, uidRec.curProcState);
23820                if (uidRec.foregroundServices) {
23821                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
23822                }
23823            }
23824        }
23825        if (mLocalPowerManager != null) {
23826            mLocalPowerManager.finishUidChanges();
23827        }
23828
23829        if (becameIdle != null) {
23830            // If we have any new uids that became idle this time, we need to make sure
23831            // they aren't left with running services.
23832            for (int i = becameIdle.size() - 1; i >= 0; i--) {
23833                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
23834            }
23835        }
23836
23837        if (mProcessStats.shouldWriteNowLocked(now)) {
23838            mHandler.post(new Runnable() {
23839                @Override public void run() {
23840                    synchronized (ActivityManagerService.this) {
23841                        mProcessStats.writeStateAsyncLocked();
23842                    }
23843                }
23844            });
23845        }
23846
23847        if (DEBUG_OOM_ADJ) {
23848            final long duration = SystemClock.uptimeMillis() - now;
23849            if (false) {
23850                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
23851                        new RuntimeException("here").fillInStackTrace());
23852            } else {
23853                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
23854            }
23855        }
23856    }
23857
23858    @Override
23859    public void makePackageIdle(String packageName, int userId) {
23860        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23861                != PackageManager.PERMISSION_GRANTED) {
23862            String msg = "Permission Denial: makePackageIdle() from pid="
23863                    + Binder.getCallingPid()
23864                    + ", uid=" + Binder.getCallingUid()
23865                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23866            Slog.w(TAG, msg);
23867            throw new SecurityException(msg);
23868        }
23869        final int callingPid = Binder.getCallingPid();
23870        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23871                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23872        long callingId = Binder.clearCallingIdentity();
23873        synchronized(this) {
23874            try {
23875                IPackageManager pm = AppGlobals.getPackageManager();
23876                int pkgUid = -1;
23877                try {
23878                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23879                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23880                } catch (RemoteException e) {
23881                }
23882                if (pkgUid == -1) {
23883                    throw new IllegalArgumentException("Unknown package name " + packageName);
23884                }
23885
23886                if (mLocalPowerManager != null) {
23887                    mLocalPowerManager.startUidChanges();
23888                }
23889                final int appId = UserHandle.getAppId(pkgUid);
23890                final int N = mActiveUids.size();
23891                for (int i=N-1; i>=0; i--) {
23892                    final UidRecord uidRec = mActiveUids.valueAt(i);
23893                    final long bgTime = uidRec.lastBackgroundTime;
23894                    if (bgTime > 0 && !uidRec.idle) {
23895                        if (UserHandle.getAppId(uidRec.uid) == appId) {
23896                            if (userId == UserHandle.USER_ALL ||
23897                                    userId == UserHandle.getUserId(uidRec.uid)) {
23898                                EventLogTags.writeAmUidIdle(uidRec.uid);
23899                                uidRec.idle = true;
23900                                uidRec.setIdle = true;
23901                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23902                                        + " from package " + packageName + " user " + userId);
23903                                doStopUidLocked(uidRec.uid, uidRec);
23904                            }
23905                        }
23906                    }
23907                }
23908            } finally {
23909                if (mLocalPowerManager != null) {
23910                    mLocalPowerManager.finishUidChanges();
23911                }
23912                Binder.restoreCallingIdentity(callingId);
23913            }
23914        }
23915    }
23916
23917    final void idleUids() {
23918        synchronized (this) {
23919            final int N = mActiveUids.size();
23920            if (N <= 0) {
23921                return;
23922            }
23923            final long nowElapsed = SystemClock.elapsedRealtime();
23924            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23925            long nextTime = 0;
23926            if (mLocalPowerManager != null) {
23927                mLocalPowerManager.startUidChanges();
23928            }
23929            for (int i=N-1; i>=0; i--) {
23930                final UidRecord uidRec = mActiveUids.valueAt(i);
23931                final long bgTime = uidRec.lastBackgroundTime;
23932                if (bgTime > 0 && !uidRec.idle) {
23933                    if (bgTime <= maxBgTime) {
23934                        EventLogTags.writeAmUidIdle(uidRec.uid);
23935                        uidRec.idle = true;
23936                        uidRec.setIdle = true;
23937                        doStopUidLocked(uidRec.uid, uidRec);
23938                    } else {
23939                        if (nextTime == 0 || nextTime > bgTime) {
23940                            nextTime = bgTime;
23941                        }
23942                    }
23943                }
23944            }
23945            if (mLocalPowerManager != null) {
23946                mLocalPowerManager.finishUidChanges();
23947            }
23948            if (nextTime > 0) {
23949                mHandler.removeMessages(IDLE_UIDS_MSG);
23950                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23951                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23952            }
23953        }
23954    }
23955
23956    /**
23957     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23958     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23959     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23960     */
23961    @VisibleForTesting
23962    @GuardedBy("this")
23963    void incrementProcStateSeqAndNotifyAppsLocked() {
23964        if (mWaitForNetworkTimeoutMs <= 0) {
23965            return;
23966        }
23967        // Used for identifying which uids need to block for network.
23968        ArrayList<Integer> blockingUids = null;
23969        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23970            final UidRecord uidRec = mActiveUids.valueAt(i);
23971            // If the network is not restricted for uid, then nothing to do here.
23972            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23973                continue;
23974            }
23975            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23976                continue;
23977            }
23978            // If process state is not changed, then there's nothing to do.
23979            if (uidRec.setProcState == uidRec.curProcState) {
23980                continue;
23981            }
23982            final int blockState = getBlockStateForUid(uidRec);
23983            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23984            // there's nothing the app needs to do in this scenario.
23985            if (blockState == NETWORK_STATE_NO_CHANGE) {
23986                continue;
23987            }
23988            synchronized (uidRec.networkStateLock) {
23989                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23990                if (blockState == NETWORK_STATE_BLOCK) {
23991                    if (blockingUids == null) {
23992                        blockingUids = new ArrayList<>();
23993                    }
23994                    blockingUids.add(uidRec.uid);
23995                } else {
23996                    if (DEBUG_NETWORK) {
23997                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23998                                + " threads for uid: " + uidRec);
23999                    }
24000                    if (uidRec.waitingForNetwork) {
24001                        uidRec.networkStateLock.notifyAll();
24002                    }
24003                }
24004            }
24005        }
24006
24007        // There are no uids that need to block, so nothing more to do.
24008        if (blockingUids == null) {
24009            return;
24010        }
24011
24012        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
24013            final ProcessRecord app = mLruProcesses.get(i);
24014            if (!blockingUids.contains(app.uid)) {
24015                continue;
24016            }
24017            if (!app.killedByAm && app.thread != null) {
24018                final UidRecord uidRec = mActiveUids.get(app.uid);
24019                try {
24020                    if (DEBUG_NETWORK) {
24021                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
24022                                + uidRec);
24023                    }
24024                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
24025                } catch (RemoteException ignored) {
24026                }
24027            }
24028        }
24029    }
24030
24031    /**
24032     * Checks if the uid is coming from background to foreground or vice versa and returns
24033     * appropriate block state based on this.
24034     *
24035     * @return blockState based on whether the uid is coming from background to foreground or
24036     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
24037     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
24038     *         {@link #NETWORK_STATE_NO_CHANGE}.
24039     */
24040    @VisibleForTesting
24041    int getBlockStateForUid(UidRecord uidRec) {
24042        // Denotes whether uid's process state is currently allowed network access.
24043        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
24044                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
24045        // Denotes whether uid's process state was previously allowed network access.
24046        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
24047                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
24048
24049        // When the uid is coming to foreground, AMS should inform the app thread that it should
24050        // block for the network rules to get updated before launching an activity.
24051        if (!wasAllowed && isAllowed) {
24052            return NETWORK_STATE_BLOCK;
24053        }
24054        // When the uid is going to background, AMS should inform the app thread that if an
24055        // activity launch is blocked for the network rules to get updated, it should be unblocked.
24056        if (wasAllowed && !isAllowed) {
24057            return NETWORK_STATE_UNBLOCK;
24058        }
24059        return NETWORK_STATE_NO_CHANGE;
24060    }
24061
24062    final void runInBackgroundDisabled(int uid) {
24063        synchronized (this) {
24064            UidRecord uidRec = mActiveUids.get(uid);
24065            if (uidRec != null) {
24066                // This uid is actually running...  should it be considered background now?
24067                if (uidRec.idle) {
24068                    doStopUidLocked(uidRec.uid, uidRec);
24069                }
24070            } else {
24071                // This uid isn't actually running...  still send a report about it being "stopped".
24072                doStopUidLocked(uid, null);
24073            }
24074        }
24075    }
24076
24077    /**
24078     * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
24079     */
24080    void doStopUidForIdleUidsLocked() {
24081        final int size = mActiveUids.size();
24082        for (int i = 0; i < size; i++) {
24083            final int uid = mActiveUids.keyAt(i);
24084            if (!UserHandle.isApp(uid)) {
24085                continue;
24086            }
24087            final UidRecord uidRec = mActiveUids.valueAt(i);
24088            if (!uidRec.idle) {
24089                continue;
24090            }
24091            doStopUidLocked(uidRec.uid, uidRec);
24092        }
24093    }
24094
24095    final void doStopUidLocked(int uid, final UidRecord uidRec) {
24096        mServices.stopInBackgroundLocked(uid);
24097        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
24098    }
24099
24100    /**
24101     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
24102     */
24103    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
24104            long duration, String tag) {
24105        if (DEBUG_WHITELISTS) {
24106            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
24107                    + targetUid + ", " + duration + ")");
24108        }
24109
24110        synchronized (mPidsSelfLocked) {
24111            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
24112            if (pr == null) {
24113                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
24114                        + callerPid);
24115                return;
24116            }
24117            if (!pr.whitelistManager) {
24118                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
24119                        != PackageManager.PERMISSION_GRANTED) {
24120                    if (DEBUG_WHITELISTS) {
24121                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
24122                                + ": pid " + callerPid + " is not allowed");
24123                    }
24124                    return;
24125                }
24126            }
24127        }
24128
24129        tempWhitelistUidLocked(targetUid, duration, tag);
24130    }
24131
24132    /**
24133     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
24134     */
24135    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
24136        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
24137        setUidTempWhitelistStateLocked(targetUid, true);
24138        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
24139    }
24140
24141    void pushTempWhitelist() {
24142        final int N;
24143        final PendingTempWhitelist[] list;
24144
24145        // First copy out the pending changes...  we need to leave them in the map for now,
24146        // in case someone needs to check what is coming up while we don't have the lock held.
24147        synchronized(this) {
24148            N = mPendingTempWhitelist.size();
24149            list = new PendingTempWhitelist[N];
24150            for (int i = 0; i < N; i++) {
24151                list[i] = mPendingTempWhitelist.valueAt(i);
24152            }
24153        }
24154
24155        // Now safely dispatch changes to device idle controller.
24156        for (int i = 0; i < N; i++) {
24157            PendingTempWhitelist ptw = list[i];
24158            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
24159                    ptw.duration, true, ptw.tag);
24160        }
24161
24162        // And now we can safely remove them from the map.
24163        synchronized(this) {
24164            for (int i = 0; i < N; i++) {
24165                PendingTempWhitelist ptw = list[i];
24166                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
24167                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
24168                    mPendingTempWhitelist.removeAt(index);
24169                }
24170            }
24171        }
24172    }
24173
24174    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
24175        boolean changed = false;
24176        for (int i=mActiveUids.size()-1; i>=0; i--) {
24177            final UidRecord uidRec = mActiveUids.valueAt(i);
24178            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
24179                uidRec.curWhitelist = onWhitelist;
24180                changed = true;
24181            }
24182        }
24183        if (changed) {
24184            updateOomAdjLocked();
24185        }
24186    }
24187
24188    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
24189        boolean changed = false;
24190        final UidRecord uidRec = mActiveUids.get(uid);
24191        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
24192            uidRec.curWhitelist = onWhitelist;
24193            updateOomAdjLocked();
24194        }
24195    }
24196
24197    final void trimApplications() {
24198        synchronized (this) {
24199            int i;
24200
24201            // First remove any unused application processes whose package
24202            // has been removed.
24203            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
24204                final ProcessRecord app = mRemovedProcesses.get(i);
24205                if (app.activities.size() == 0 && app.recentTasks.size() == 0
24206                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
24207                    Slog.i(
24208                        TAG, "Exiting empty application process "
24209                        + app.toShortString() + " ("
24210                        + (app.thread != null ? app.thread.asBinder() : null)
24211                        + ")\n");
24212                    if (app.pid > 0 && app.pid != MY_PID) {
24213                        app.kill("empty", false);
24214                    } else if (app.thread != null) {
24215                        try {
24216                            app.thread.scheduleExit();
24217                        } catch (Exception e) {
24218                            // Ignore exceptions.
24219                        }
24220                    }
24221                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
24222                    mRemovedProcesses.remove(i);
24223
24224                    if (app.persistent) {
24225                        addAppLocked(app.info, null, false, null /* ABI override */);
24226                    }
24227                }
24228            }
24229
24230            // Now update the oom adj for all processes.
24231            updateOomAdjLocked();
24232        }
24233    }
24234
24235    /** This method sends the specified signal to each of the persistent apps */
24236    public void signalPersistentProcesses(int sig) throws RemoteException {
24237        if (sig != SIGNAL_USR1) {
24238            throw new SecurityException("Only SIGNAL_USR1 is allowed");
24239        }
24240
24241        synchronized (this) {
24242            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
24243                    != PackageManager.PERMISSION_GRANTED) {
24244                throw new SecurityException("Requires permission "
24245                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
24246            }
24247
24248            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
24249                ProcessRecord r = mLruProcesses.get(i);
24250                if (r.thread != null && r.persistent) {
24251                    sendSignal(r.pid, sig);
24252                }
24253            }
24254        }
24255    }
24256
24257    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
24258        if (proc == null || proc == mProfileProc) {
24259            proc = mProfileProc;
24260            profileType = mProfileType;
24261            clearProfilerLocked();
24262        }
24263        if (proc == null) {
24264            return;
24265        }
24266        try {
24267            proc.thread.profilerControl(false, null, profileType);
24268        } catch (RemoteException e) {
24269            throw new IllegalStateException("Process disappeared");
24270        }
24271    }
24272
24273    private void clearProfilerLocked() {
24274        if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
24275            try {
24276                mProfilerInfo.profileFd.close();
24277            } catch (IOException e) {
24278            }
24279        }
24280        mProfileApp = null;
24281        mProfileProc = null;
24282        mProfilerInfo = null;
24283    }
24284
24285    public boolean profileControl(String process, int userId, boolean start,
24286            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
24287
24288        try {
24289            synchronized (this) {
24290                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
24291                // its own permission.
24292                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
24293                        != PackageManager.PERMISSION_GRANTED) {
24294                    throw new SecurityException("Requires permission "
24295                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
24296                }
24297
24298                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
24299                    throw new IllegalArgumentException("null profile info or fd");
24300                }
24301
24302                ProcessRecord proc = null;
24303                if (process != null) {
24304                    proc = findProcessLocked(process, userId, "profileControl");
24305                }
24306
24307                if (start && (proc == null || proc.thread == null)) {
24308                    throw new IllegalArgumentException("Unknown process: " + process);
24309                }
24310
24311                if (start) {
24312                    stopProfilerLocked(null, 0);
24313                    setProfileApp(proc.info, proc.processName, profilerInfo);
24314                    mProfileProc = proc;
24315                    mProfileType = profileType;
24316                    ParcelFileDescriptor fd = profilerInfo.profileFd;
24317                    try {
24318                        fd = fd.dup();
24319                    } catch (IOException e) {
24320                        fd = null;
24321                    }
24322                    profilerInfo.profileFd = fd;
24323                    proc.thread.profilerControl(start, profilerInfo, profileType);
24324                    fd = null;
24325                    try {
24326                        mProfilerInfo.profileFd.close();
24327                    } catch (IOException e) {
24328                    }
24329                    mProfilerInfo.profileFd = null;
24330                } else {
24331                    stopProfilerLocked(proc, profileType);
24332                    if (profilerInfo != null && profilerInfo.profileFd != null) {
24333                        try {
24334                            profilerInfo.profileFd.close();
24335                        } catch (IOException e) {
24336                        }
24337                    }
24338                }
24339
24340                return true;
24341            }
24342        } catch (RemoteException e) {
24343            throw new IllegalStateException("Process disappeared");
24344        } finally {
24345            if (profilerInfo != null && profilerInfo.profileFd != null) {
24346                try {
24347                    profilerInfo.profileFd.close();
24348                } catch (IOException e) {
24349                }
24350            }
24351        }
24352    }
24353
24354    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
24355        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
24356                userId, true, ALLOW_FULL_ONLY, callName, null);
24357        ProcessRecord proc = null;
24358        try {
24359            int pid = Integer.parseInt(process);
24360            synchronized (mPidsSelfLocked) {
24361                proc = mPidsSelfLocked.get(pid);
24362            }
24363        } catch (NumberFormatException e) {
24364        }
24365
24366        if (proc == null) {
24367            ArrayMap<String, SparseArray<ProcessRecord>> all
24368                    = mProcessNames.getMap();
24369            SparseArray<ProcessRecord> procs = all.get(process);
24370            if (procs != null && procs.size() > 0) {
24371                proc = procs.valueAt(0);
24372                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
24373                    for (int i=1; i<procs.size(); i++) {
24374                        ProcessRecord thisProc = procs.valueAt(i);
24375                        if (thisProc.userId == userId) {
24376                            proc = thisProc;
24377                            break;
24378                        }
24379                    }
24380                }
24381            }
24382        }
24383
24384        return proc;
24385    }
24386
24387    public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
24388            boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
24389
24390        try {
24391            synchronized (this) {
24392                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
24393                // its own permission (same as profileControl).
24394                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
24395                        != PackageManager.PERMISSION_GRANTED) {
24396                    throw new SecurityException("Requires permission "
24397                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
24398                }
24399
24400                if (fd == null) {
24401                    throw new IllegalArgumentException("null fd");
24402                }
24403
24404                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
24405                if (proc == null || proc.thread == null) {
24406                    throw new IllegalArgumentException("Unknown process: " + process);
24407                }
24408
24409                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24410                if (!isDebuggable) {
24411                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24412                        throw new SecurityException("Process not debuggable: " + proc);
24413                    }
24414                }
24415
24416                proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
24417                fd = null;
24418                return true;
24419            }
24420        } catch (RemoteException e) {
24421            throw new IllegalStateException("Process disappeared");
24422        } finally {
24423            if (fd != null) {
24424                try {
24425                    fd.close();
24426                } catch (IOException e) {
24427                }
24428            }
24429        }
24430    }
24431
24432    @Override
24433    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
24434            String reportPackage) {
24435        if (processName != null) {
24436            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
24437                    "setDumpHeapDebugLimit()");
24438        } else {
24439            synchronized (mPidsSelfLocked) {
24440                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
24441                if (proc == null) {
24442                    throw new SecurityException("No process found for calling pid "
24443                            + Binder.getCallingPid());
24444                }
24445                if (!Build.IS_DEBUGGABLE
24446                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24447                    throw new SecurityException("Not running a debuggable build");
24448                }
24449                processName = proc.processName;
24450                uid = proc.uid;
24451                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
24452                    throw new SecurityException("Package " + reportPackage + " is not running in "
24453                            + proc);
24454                }
24455            }
24456        }
24457        synchronized (this) {
24458            if (maxMemSize > 0) {
24459                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
24460            } else {
24461                if (uid != 0) {
24462                    mMemWatchProcesses.remove(processName, uid);
24463                } else {
24464                    mMemWatchProcesses.getMap().remove(processName);
24465                }
24466            }
24467        }
24468    }
24469
24470    @Override
24471    public void dumpHeapFinished(String path) {
24472        synchronized (this) {
24473            if (Binder.getCallingPid() != mMemWatchDumpPid) {
24474                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
24475                        + " does not match last pid " + mMemWatchDumpPid);
24476                return;
24477            }
24478            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
24479                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
24480                        + " does not match last path " + mMemWatchDumpFile);
24481                return;
24482            }
24483            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
24484            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
24485
24486            // Forced gc to clean up the remnant hprof fd.
24487            Runtime.getRuntime().gc();
24488        }
24489    }
24490
24491    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
24492    public void monitor() {
24493        synchronized (this) { }
24494    }
24495
24496    void onCoreSettingsChange(Bundle settings) {
24497        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24498            ProcessRecord processRecord = mLruProcesses.get(i);
24499            try {
24500                if (processRecord.thread != null) {
24501                    processRecord.thread.setCoreSettings(settings);
24502                }
24503            } catch (RemoteException re) {
24504                /* ignore */
24505            }
24506        }
24507    }
24508
24509    // Multi-user methods
24510
24511    /**
24512     * Start user, if its not already running, but don't bring it to foreground.
24513     */
24514    @Override
24515    public boolean startUserInBackground(final int userId) {
24516        return startUserInBackgroundWithListener(userId, null);
24517    }
24518
24519    @Override
24520    public boolean startUserInBackgroundWithListener(final int userId,
24521                @Nullable IProgressListener unlockListener) {
24522        return mUserController.startUser(userId, /* foreground */ false, unlockListener);
24523    }
24524
24525    @Override
24526    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
24527        return mUserController.unlockUser(userId, token, secret, listener);
24528    }
24529
24530    @Override
24531    public boolean switchUser(final int targetUserId) {
24532        return mUserController.switchUser(targetUserId);
24533    }
24534
24535    @Override
24536    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
24537        return mUserController.stopUser(userId, force, callback);
24538    }
24539
24540    @Override
24541    public UserInfo getCurrentUser() {
24542        return mUserController.getCurrentUser();
24543    }
24544
24545    String getStartedUserState(int userId) {
24546        final UserState userState = mUserController.getStartedUserState(userId);
24547        return UserState.stateToString(userState.state);
24548    }
24549
24550    @Override
24551    public boolean isUserRunning(int userId, int flags) {
24552        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
24553                && checkCallingPermission(INTERACT_ACROSS_USERS)
24554                    != PackageManager.PERMISSION_GRANTED) {
24555            String msg = "Permission Denial: isUserRunning() from pid="
24556                    + Binder.getCallingPid()
24557                    + ", uid=" + Binder.getCallingUid()
24558                    + " requires " + INTERACT_ACROSS_USERS;
24559            Slog.w(TAG, msg);
24560            throw new SecurityException(msg);
24561        }
24562        return mUserController.isUserRunning(userId, flags);
24563    }
24564
24565    @Override
24566    public int[] getRunningUserIds() {
24567        if (checkCallingPermission(INTERACT_ACROSS_USERS)
24568                != PackageManager.PERMISSION_GRANTED) {
24569            String msg = "Permission Denial: isUserRunning() from pid="
24570                    + Binder.getCallingPid()
24571                    + ", uid=" + Binder.getCallingUid()
24572                    + " requires " + INTERACT_ACROSS_USERS;
24573            Slog.w(TAG, msg);
24574            throw new SecurityException(msg);
24575        }
24576        return mUserController.getStartedUserArray();
24577    }
24578
24579    @Override
24580    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
24581        mUserController.registerUserSwitchObserver(observer, name);
24582    }
24583
24584    @Override
24585    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
24586        mUserController.unregisterUserSwitchObserver(observer);
24587    }
24588
24589    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
24590        if (info == null) return null;
24591        ApplicationInfo newInfo = new ApplicationInfo(info);
24592        newInfo.initForUser(userId);
24593        return newInfo;
24594    }
24595
24596    public boolean isUserStopped(int userId) {
24597        return mUserController.getStartedUserState(userId) == null;
24598    }
24599
24600    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
24601        if (aInfo == null
24602                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
24603            return aInfo;
24604        }
24605
24606        ActivityInfo info = new ActivityInfo(aInfo);
24607        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
24608        return info;
24609    }
24610
24611    private boolean processSanityChecksLocked(ProcessRecord process) {
24612        if (process == null || process.thread == null) {
24613            return false;
24614        }
24615
24616        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24617        if (!isDebuggable) {
24618            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24619                return false;
24620            }
24621        }
24622
24623        return true;
24624    }
24625
24626    public boolean startBinderTracking() throws RemoteException {
24627        synchronized (this) {
24628            mBinderTransactionTrackingEnabled = true;
24629            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
24630            // permission (same as profileControl).
24631            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
24632                    != PackageManager.PERMISSION_GRANTED) {
24633                throw new SecurityException("Requires permission "
24634                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
24635            }
24636
24637            for (int i = 0; i < mLruProcesses.size(); i++) {
24638                ProcessRecord process = mLruProcesses.get(i);
24639                if (!processSanityChecksLocked(process)) {
24640                    continue;
24641                }
24642                try {
24643                    process.thread.startBinderTracking();
24644                } catch (RemoteException e) {
24645                    Log.v(TAG, "Process disappared");
24646                }
24647            }
24648            return true;
24649        }
24650    }
24651
24652    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
24653        try {
24654            synchronized (this) {
24655                mBinderTransactionTrackingEnabled = false;
24656                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
24657                // permission (same as profileControl).
24658                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
24659                        != PackageManager.PERMISSION_GRANTED) {
24660                    throw new SecurityException("Requires permission "
24661                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
24662                }
24663
24664                if (fd == null) {
24665                    throw new IllegalArgumentException("null fd");
24666                }
24667
24668                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
24669                pw.println("Binder transaction traces for all processes.\n");
24670                for (ProcessRecord process : mLruProcesses) {
24671                    if (!processSanityChecksLocked(process)) {
24672                        continue;
24673                    }
24674
24675                    pw.println("Traces for process: " + process.processName);
24676                    pw.flush();
24677                    try {
24678                        TransferPipe tp = new TransferPipe();
24679                        try {
24680                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
24681                            tp.go(fd.getFileDescriptor());
24682                        } finally {
24683                            tp.kill();
24684                        }
24685                    } catch (IOException e) {
24686                        pw.println("Failure while dumping IPC traces from " + process +
24687                                ".  Exception: " + e);
24688                        pw.flush();
24689                    } catch (RemoteException e) {
24690                        pw.println("Got a RemoteException while dumping IPC traces from " +
24691                                process + ".  Exception: " + e);
24692                        pw.flush();
24693                    }
24694                }
24695                fd = null;
24696                return true;
24697            }
24698        } finally {
24699            if (fd != null) {
24700                try {
24701                    fd.close();
24702                } catch (IOException e) {
24703                }
24704            }
24705        }
24706    }
24707
24708    @VisibleForTesting
24709    final class LocalService extends ActivityManagerInternal {
24710        @Override
24711        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
24712                int targetUserId) {
24713            synchronized (ActivityManagerService.this) {
24714                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
24715                        targetPkg, intent, null, targetUserId);
24716            }
24717        }
24718
24719        @Override
24720        public String checkContentProviderAccess(String authority, int userId) {
24721            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
24722        }
24723
24724        @Override
24725        public void onWakefulnessChanged(int wakefulness) {
24726            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
24727        }
24728
24729        @Override
24730        public boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
24731                String processName, String abiOverride, int uid, Runnable crashHandler) {
24732            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
24733                    processName, abiOverride, uid, crashHandler);
24734        }
24735
24736        @Override
24737        public SleepToken acquireSleepToken(String tag, int displayId) {
24738            Preconditions.checkNotNull(tag);
24739            return ActivityManagerService.this.acquireSleepToken(tag, displayId);
24740        }
24741
24742        @Override
24743        public ComponentName getHomeActivityForUser(int userId) {
24744            synchronized (ActivityManagerService.this) {
24745                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
24746                return homeActivity == null ? null : homeActivity.realActivity;
24747            }
24748        }
24749
24750        @Override
24751        public void onUserRemoved(int userId) {
24752            synchronized (ActivityManagerService.this) {
24753                ActivityManagerService.this.onUserStoppedLocked(userId);
24754            }
24755            mBatteryStatsService.onUserRemoved(userId);
24756            mUserController.onUserRemoved(userId);
24757        }
24758
24759        @Override
24760        public void onLocalVoiceInteractionStarted(IBinder activity,
24761                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
24762            synchronized (ActivityManagerService.this) {
24763                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
24764                        voiceSession, voiceInteractor);
24765            }
24766        }
24767
24768        @Override
24769        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
24770            synchronized (ActivityManagerService.this) {
24771                mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
24772                        reasons, timestamp);
24773            }
24774        }
24775
24776        @Override
24777        public void notifyAppTransitionFinished() {
24778            synchronized (ActivityManagerService.this) {
24779                mStackSupervisor.notifyAppTransitionDone();
24780            }
24781        }
24782
24783        @Override
24784        public void notifyAppTransitionCancelled() {
24785            synchronized (ActivityManagerService.this) {
24786                mStackSupervisor.notifyAppTransitionDone();
24787            }
24788        }
24789
24790        @Override
24791        public List<IBinder> getTopVisibleActivities() {
24792            synchronized (ActivityManagerService.this) {
24793                return mStackSupervisor.getTopVisibleActivities();
24794            }
24795        }
24796
24797        @Override
24798        public void notifyDockedStackMinimizedChanged(boolean minimized) {
24799            synchronized (ActivityManagerService.this) {
24800                mStackSupervisor.setDockedStackMinimized(minimized);
24801            }
24802        }
24803
24804        @Override
24805        public void killForegroundAppsForUser(int userHandle) {
24806            synchronized (ActivityManagerService.this) {
24807                final ArrayList<ProcessRecord> procs = new ArrayList<>();
24808                final int NP = mProcessNames.getMap().size();
24809                for (int ip = 0; ip < NP; ip++) {
24810                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
24811                    final int NA = apps.size();
24812                    for (int ia = 0; ia < NA; ia++) {
24813                        final ProcessRecord app = apps.valueAt(ia);
24814                        if (app.persistent) {
24815                            // We don't kill persistent processes.
24816                            continue;
24817                        }
24818                        if (app.removed) {
24819                            procs.add(app);
24820                        } else if (app.userId == userHandle && app.foregroundActivities) {
24821                            app.removed = true;
24822                            procs.add(app);
24823                        }
24824                    }
24825                }
24826
24827                final int N = procs.size();
24828                for (int i = 0; i < N; i++) {
24829                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
24830                }
24831            }
24832        }
24833
24834        @Override
24835        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24836                long duration) {
24837            if (!(target instanceof PendingIntentRecord)) {
24838                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24839                return;
24840            }
24841            synchronized (ActivityManagerService.this) {
24842                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24843            }
24844        }
24845
24846        @Override
24847        public void setDeviceIdleWhitelist(int[] appids) {
24848            synchronized (ActivityManagerService.this) {
24849                mDeviceIdleWhitelist = appids;
24850            }
24851        }
24852
24853        @Override
24854        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24855            synchronized (ActivityManagerService.this) {
24856                mDeviceIdleTempWhitelist = appids;
24857                setAppIdTempWhitelistStateLocked(changingAppId, adding);
24858            }
24859        }
24860
24861        @Override
24862        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24863                int userId) {
24864            Preconditions.checkNotNull(values, "Configuration must not be null");
24865            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24866            synchronized (ActivityManagerService.this) {
24867                updateConfigurationLocked(values, null, false, true, userId,
24868                        false /* deferResume */);
24869            }
24870        }
24871
24872        @Override
24873        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24874                Bundle bOptions) {
24875            Preconditions.checkNotNull(intents, "intents");
24876            final String[] resolvedTypes = new String[intents.length];
24877            for (int i = 0; i < intents.length; i++) {
24878                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24879            }
24880
24881            // UID of the package on user userId.
24882            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24883            // packageUid may not be initialized.
24884            int packageUid = 0;
24885            try {
24886                packageUid = AppGlobals.getPackageManager().getPackageUid(
24887                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24888            } catch (RemoteException e) {
24889                // Shouldn't happen.
24890            }
24891
24892            synchronized (ActivityManagerService.this) {
24893                return mActivityStartController.startActivitiesInPackage(packageUid, packageName,
24894                        intents, resolvedTypes, /*resultTo*/ null, bOptions, userId);
24895            }
24896        }
24897
24898        @Override
24899        public int getUidProcessState(int uid) {
24900            return getUidState(uid);
24901        }
24902
24903        @Override
24904        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24905            synchronized (ActivityManagerService.this) {
24906
24907                // We might change the visibilities here, so prepare an empty app transition which
24908                // might be overridden later if we actually change visibilities.
24909                final boolean wasTransitionSet =
24910                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24911                if (!wasTransitionSet) {
24912                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
24913                            false /* alwaysKeepCurrent */);
24914                }
24915                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24916
24917                // If there was a transition set already we don't want to interfere with it as we
24918                // might be starting it too early.
24919                if (!wasTransitionSet) {
24920                    mWindowManager.executeAppTransition();
24921                }
24922            }
24923            if (callback != null) {
24924                callback.run();
24925            }
24926        }
24927
24928        @Override
24929        public boolean isSystemReady() {
24930            // no need to synchronize(this) just to read & return the value
24931            return mSystemReady;
24932        }
24933
24934        @Override
24935        public void notifyKeyguardTrustedChanged() {
24936            synchronized (ActivityManagerService.this) {
24937                if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24938                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24939                }
24940            }
24941        }
24942
24943        /**
24944         * Sets if the given pid has an overlay UI or not.
24945         *
24946         * @param pid The pid we are setting overlay UI for.
24947         * @param hasOverlayUi True if the process has overlay UI.
24948         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24949         */
24950        @Override
24951        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24952            synchronized (ActivityManagerService.this) {
24953                final ProcessRecord pr;
24954                synchronized (mPidsSelfLocked) {
24955                    pr = mPidsSelfLocked.get(pid);
24956                    if (pr == null) {
24957                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24958                        return;
24959                    }
24960                }
24961                if (pr.hasOverlayUi == hasOverlayUi) {
24962                    return;
24963                }
24964                pr.hasOverlayUi = hasOverlayUi;
24965                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24966                updateOomAdjLocked(pr, true);
24967            }
24968        }
24969
24970        /**
24971         * Called after the network policy rules are updated by
24972         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24973         * and {@param procStateSeq}.
24974         */
24975        @Override
24976        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24977            if (DEBUG_NETWORK) {
24978                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24979                        + uid + " seq: " + procStateSeq);
24980            }
24981            UidRecord record;
24982            synchronized (ActivityManagerService.this) {
24983                record = mActiveUids.get(uid);
24984                if (record == null) {
24985                    if (DEBUG_NETWORK) {
24986                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24987                                + " procStateSeq: " + procStateSeq);
24988                    }
24989                    return;
24990                }
24991            }
24992            synchronized (record.networkStateLock) {
24993                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24994                    if (DEBUG_NETWORK) {
24995                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24996                                + " been handled for uid: " + uid);
24997                    }
24998                    return;
24999                }
25000                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
25001                if (record.curProcStateSeq > procStateSeq) {
25002                    if (DEBUG_NETWORK) {
25003                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
25004                                + ", curProcstateSeq: " + record.curProcStateSeq
25005                                + ", procStateSeq: " + procStateSeq);
25006                    }
25007                    return;
25008                }
25009                if (record.waitingForNetwork) {
25010                    if (DEBUG_NETWORK) {
25011                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
25012                                + ", procStateSeq: " + procStateSeq);
25013                    }
25014                    record.networkStateLock.notifyAll();
25015                }
25016            }
25017        }
25018
25019        @Override
25020        public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
25021            synchronized (ActivityManagerService.this) {
25022                mActiveVoiceInteractionServiceComponent = component;
25023            }
25024        }
25025
25026        /**
25027         * Called after virtual display Id is updated by
25028         * {@link com.android.server.vr.Vr2dDisplay} with a specific
25029         * {@param vrVr2dDisplayId}.
25030         */
25031        @Override
25032        public void setVr2dDisplayId(int vr2dDisplayId) {
25033            if (DEBUG_STACK) {
25034                Slog.d(TAG, "setVr2dDisplayId called for: " +
25035                        vr2dDisplayId);
25036            }
25037            synchronized (ActivityManagerService.this) {
25038                mVr2dDisplayId = vr2dDisplayId;
25039            }
25040        }
25041
25042        @Override
25043        public void saveANRState(String reason) {
25044            synchronized (ActivityManagerService.this) {
25045                final StringWriter sw = new StringWriter();
25046                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
25047                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
25048                if (reason != null) {
25049                    pw.println("  Reason: " + reason);
25050                }
25051                pw.println();
25052                mActivityStartController.dump(pw, "  ", null);
25053                pw.println();
25054                pw.println("-------------------------------------------------------------------------------");
25055                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
25056                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
25057                        "" /* header */);
25058                pw.println();
25059                pw.close();
25060
25061                mLastANRState = sw.toString();
25062            }
25063        }
25064
25065        @Override
25066        public void clearSavedANRState() {
25067            synchronized (ActivityManagerService.this) {
25068                mLastANRState = null;
25069            }
25070        }
25071
25072        @Override
25073        public void setFocusedActivity(IBinder token) {
25074            synchronized (ActivityManagerService.this) {
25075                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
25076                if (r == null) {
25077                    throw new IllegalArgumentException(
25078                            "setFocusedActivity: No activity record matching token=" + token);
25079                }
25080                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
25081                        r, "setFocusedActivity")) {
25082                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
25083                }
25084            }
25085        }
25086
25087        @Override
25088        public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
25089            synchronized (ActivityManagerService.this) {
25090                if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
25091                    ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
25092                    if (types == null) {
25093                        if (uid < 0) {
25094                            return;
25095                        }
25096                        types = new ArrayMap<>();
25097                        mAllowAppSwitchUids.put(userId, types);
25098                    }
25099                    if (uid < 0) {
25100                        types.remove(type);
25101                    } else {
25102                        types.put(type, uid);
25103                    }
25104                }
25105            }
25106        }
25107
25108        @Override
25109        public boolean isRuntimeRestarted() {
25110            return mSystemServiceManager.isRuntimeRestarted();
25111        }
25112
25113        @Override
25114        public boolean hasRunningActivity(int uid, @Nullable String packageName) {
25115            if (packageName == null) return false;
25116
25117            synchronized (ActivityManagerService.this) {
25118                for (int i = 0; i < mLruProcesses.size(); i++) {
25119                    final ProcessRecord processRecord = mLruProcesses.get(i);
25120                    if (processRecord.uid == uid) {
25121                        for (int j = 0; j < processRecord.activities.size(); j++) {
25122                            final ActivityRecord activityRecord = processRecord.activities.get(j);
25123                            if (packageName.equals(activityRecord.packageName)) {
25124                                return true;
25125                            }
25126                        }
25127                    }
25128                }
25129            }
25130            return false;
25131        }
25132
25133        @Override
25134        public void registerScreenObserver(ScreenObserver observer) {
25135            mScreenObservers.add(observer);
25136        }
25137
25138        @Override
25139        public boolean canStartMoreUsers() {
25140            return mUserController.canStartMoreUsers();
25141        }
25142    }
25143
25144    /**
25145     * Called by app main thread to wait for the network policy rules to get updated.
25146     *
25147     * @param procStateSeq The sequence number indicating the process state change that the main
25148     *                     thread is interested in.
25149     */
25150    @Override
25151    public void waitForNetworkStateUpdate(long procStateSeq) {
25152        final int callingUid = Binder.getCallingUid();
25153        if (DEBUG_NETWORK) {
25154            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
25155        }
25156        UidRecord record;
25157        synchronized (this) {
25158            record = mActiveUids.get(callingUid);
25159            if (record == null) {
25160                return;
25161            }
25162        }
25163        synchronized (record.networkStateLock) {
25164            if (record.lastDispatchedProcStateSeq < procStateSeq) {
25165                if (DEBUG_NETWORK) {
25166                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
25167                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
25168                            + " lastProcStateSeqDispatchedToObservers: "
25169                            + record.lastDispatchedProcStateSeq);
25170                }
25171                return;
25172            }
25173            if (record.curProcStateSeq > procStateSeq) {
25174                if (DEBUG_NETWORK) {
25175                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
25176                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
25177                            + ", procStateSeq: " + procStateSeq);
25178                }
25179                return;
25180            }
25181            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
25182                if (DEBUG_NETWORK) {
25183                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
25184                            + procStateSeq + ", so no need to wait. Uid: "
25185                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
25186                            + record.lastNetworkUpdatedProcStateSeq);
25187                }
25188                return;
25189            }
25190            try {
25191                if (DEBUG_NETWORK) {
25192                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
25193                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
25194                }
25195                final long startTime = SystemClock.uptimeMillis();
25196                record.waitingForNetwork = true;
25197                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
25198                record.waitingForNetwork = false;
25199                final long totalTime = SystemClock.uptimeMillis() - startTime;
25200                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
25201                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
25202                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
25203                            + procStateSeq + " UidRec: " + record
25204                            + " validateUidRec: " + mValidateUids.get(callingUid));
25205                }
25206            } catch (InterruptedException e) {
25207                Thread.currentThread().interrupt();
25208            }
25209        }
25210    }
25211
25212    public void waitForBroadcastIdle(PrintWriter pw) {
25213        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
25214        while (true) {
25215            boolean idle = true;
25216            synchronized (this) {
25217                for (BroadcastQueue queue : mBroadcastQueues) {
25218                    if (!queue.isIdle()) {
25219                        final String msg = "Waiting for queue " + queue + " to become idle...";
25220                        pw.println(msg);
25221                        pw.flush();
25222                        Slog.v(TAG, msg);
25223                        idle = false;
25224                    }
25225                }
25226            }
25227
25228            if (idle) {
25229                final String msg = "All broadcast queues are idle!";
25230                pw.println(msg);
25231                pw.flush();
25232                Slog.v(TAG, msg);
25233                return;
25234            } else {
25235                SystemClock.sleep(1000);
25236            }
25237        }
25238    }
25239
25240    /**
25241     * Return the user id of the last resumed activity.
25242     */
25243    @Override
25244    public @UserIdInt int getLastResumedActivityUserId() {
25245        enforceCallingPermission(
25246                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
25247        synchronized (this) {
25248            if (mLastResumedActivity == null) {
25249                return mUserController.getCurrentUserId();
25250            }
25251            return mLastResumedActivity.userId;
25252        }
25253    }
25254
25255    /**
25256     * Kill processes for the user with id userId and that depend on the package named packageName
25257     */
25258    @Override
25259    public void killPackageDependents(String packageName, int userId) {
25260        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
25261        if (packageName == null) {
25262            throw new NullPointerException(
25263                    "Cannot kill the dependents of a package without its name.");
25264        }
25265
25266        long callingId = Binder.clearCallingIdentity();
25267        IPackageManager pm = AppGlobals.getPackageManager();
25268        int pkgUid = -1;
25269        try {
25270            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
25271        } catch (RemoteException e) {
25272        }
25273        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
25274            throw new IllegalArgumentException(
25275                    "Cannot kill dependents of non-existing package " + packageName);
25276        }
25277        try {
25278            synchronized(this) {
25279                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
25280                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
25281                        "dep: " + packageName);
25282            }
25283        } finally {
25284            Binder.restoreCallingIdentity(callingId);
25285        }
25286    }
25287
25288    @Override
25289    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
25290            CharSequence message) throws RemoteException {
25291        if (message != null) {
25292            enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
25293                    "dismissKeyguard()");
25294        }
25295        final long callingId = Binder.clearCallingIdentity();
25296        try {
25297            mKeyguardController.dismissKeyguard(token, callback, message);
25298        } finally {
25299            Binder.restoreCallingIdentity(callingId);
25300        }
25301    }
25302
25303    @Override
25304    public int restartUserInBackground(final int userId) {
25305        return mUserController.restartUser(userId, /* foreground */ false);
25306    }
25307
25308    @Override
25309    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
25310        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
25311                "scheduleApplicationInfoChanged()");
25312
25313        synchronized (this) {
25314            final long origId = Binder.clearCallingIdentity();
25315            try {
25316                updateApplicationInfoLocked(packageNames, userId);
25317            } finally {
25318                Binder.restoreCallingIdentity(origId);
25319            }
25320        }
25321    }
25322
25323    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
25324        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
25325        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
25326            final ProcessRecord app = mLruProcesses.get(i);
25327            if (app.thread == null) {
25328                continue;
25329            }
25330
25331            if (userId != UserHandle.USER_ALL && app.userId != userId) {
25332                continue;
25333            }
25334
25335            final int packageCount = app.pkgList.size();
25336            for (int j = 0; j < packageCount; j++) {
25337                final String packageName = app.pkgList.keyAt(j);
25338                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
25339                    try {
25340                        final ApplicationInfo ai = AppGlobals.getPackageManager()
25341                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
25342                        if (ai != null) {
25343                            app.thread.scheduleApplicationInfoChanged(ai);
25344                        }
25345                    } catch (RemoteException e) {
25346                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
25347                                    packageName, app));
25348                    }
25349                }
25350            }
25351        }
25352        if (updateFrameworkRes && mWindowManager != null) {
25353            ActivityThread.currentActivityThread().getExecutor().execute(
25354                    mWindowManager::onOverlayChanged);
25355        }
25356    }
25357
25358    /**
25359     * Attach an agent to the specified process (proces name or PID)
25360     */
25361    public void attachAgent(String process, String path) {
25362        try {
25363            synchronized (this) {
25364                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
25365                if (proc == null || proc.thread == null) {
25366                    throw new IllegalArgumentException("Unknown process: " + process);
25367                }
25368
25369                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25370                if (!isDebuggable) {
25371                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25372                        throw new SecurityException("Process not debuggable: " + proc);
25373                    }
25374                }
25375
25376                proc.thread.attachAgent(path);
25377            }
25378        } catch (RemoteException e) {
25379            throw new IllegalStateException("Process disappeared");
25380        }
25381    }
25382
25383    @VisibleForTesting
25384    public static class Injector {
25385        private NetworkManagementInternal mNmi;
25386
25387        public Context getContext() {
25388            return null;
25389        }
25390
25391        public AppOpsService getAppOpsService(File file, Handler handler) {
25392            return new AppOpsService(file, handler);
25393        }
25394
25395        public Handler getUiHandler(ActivityManagerService service) {
25396            return service.new UiHandler();
25397        }
25398
25399        public boolean isNetworkRestrictedForUid(int uid) {
25400            if (ensureHasNetworkManagementInternal()) {
25401                return mNmi.isNetworkRestrictedForUid(uid);
25402            }
25403            return false;
25404        }
25405
25406        private boolean ensureHasNetworkManagementInternal() {
25407            if (mNmi == null) {
25408                mNmi = LocalServices.getService(NetworkManagementInternal.class);
25409            }
25410            return mNmi != null;
25411        }
25412    }
25413
25414    @Override
25415    public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
25416            throws RemoteException {
25417        synchronized (this) {
25418            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
25419            if (r == null) {
25420                return;
25421            }
25422            final long origId = Binder.clearCallingIdentity();
25423            try {
25424                r.setShowWhenLocked(showWhenLocked);
25425            } finally {
25426                Binder.restoreCallingIdentity(origId);
25427            }
25428        }
25429    }
25430
25431    @Override
25432    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
25433        synchronized (this) {
25434            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
25435            if (r == null) {
25436                return;
25437            }
25438            final long origId = Binder.clearCallingIdentity();
25439            try {
25440                r.setTurnScreenOn(turnScreenOn);
25441            } finally {
25442                Binder.restoreCallingIdentity(origId);
25443            }
25444        }
25445    }
25446}
25447