ActivityManagerService.java revision 4ea0a5a2df28c3acdd72332907be2d4f38fcd061
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.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
23import static android.Manifest.permission.INTERACT_ACROSS_USERS;
24import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
25import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
26import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
27import static android.Manifest.permission.READ_FRAME_BUFFER;
28import static android.Manifest.permission.REMOVE_TASKS;
29import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
30import static android.Manifest.permission.STOP_APP_SWITCHES;
31import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
32import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
33import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
34import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
35import static android.app.ActivityManagerInternal.ASSIST_KEY_CONTENT;
36import static android.app.ActivityManagerInternal.ASSIST_KEY_DATA;
37import static android.app.ActivityManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
38import static android.app.ActivityManagerInternal.ASSIST_KEY_STRUCTURE;
39import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
40import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE;
41import static android.app.AppOpsManager.OP_NONE;
42import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
43import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
44import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
45import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
46import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
47import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
48import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
49import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
50import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
51import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
52import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
53import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
54import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
55import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
56import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
57import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
58import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
59import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
60import static android.content.pm.PackageManager.GET_PROVIDERS;
61import static android.content.pm.PackageManager.MATCH_ANY_USER;
62import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
63import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
64import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
65import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
66import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
67import static android.content.pm.PackageManager.PERMISSION_GRANTED;
68import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
69import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
70import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
71import static android.os.Build.VERSION_CODES.N;
72import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
73import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
74import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
75import static android.os.IServiceManager.DUMP_FLAG_PROTO;
76import static android.os.Process.BLUETOOTH_UID;
77import static android.os.Process.FIRST_APPLICATION_UID;
78import static android.os.Process.FIRST_ISOLATED_UID;
79import static android.os.Process.LAST_ISOLATED_UID;
80import static android.os.Process.NFC_UID;
81import static android.os.Process.PHONE_UID;
82import static android.os.Process.PROC_CHAR;
83import static android.os.Process.PROC_OUT_LONG;
84import static android.os.Process.PROC_PARENS;
85import static android.os.Process.PROC_SPACE_TERM;
86import static android.os.Process.ProcessStartResult;
87import static android.os.Process.ROOT_UID;
88import static android.os.Process.SCHED_FIFO;
89import static android.os.Process.SCHED_OTHER;
90import static android.os.Process.SCHED_RESET_ON_FORK;
91import static android.os.Process.SE_UID;
92import static android.os.Process.SHELL_UID;
93import static android.os.Process.SIGNAL_QUIT;
94import static android.os.Process.SIGNAL_USR1;
95import static android.os.Process.SYSTEM_UID;
96import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
97import static android.os.Process.THREAD_GROUP_DEFAULT;
98import static android.os.Process.THREAD_GROUP_TOP_APP;
99import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
100import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
101import static android.os.Process.getFreeMemory;
102import static android.os.Process.getTotalMemory;
103import static android.os.Process.isThreadInProcess;
104import static android.os.Process.killProcess;
105import static android.os.Process.killProcessQuiet;
106import static android.os.Process.myPid;
107import static android.os.Process.myUid;
108import static android.os.Process.readProcFile;
109import static android.os.Process.removeAllProcessGroups;
110import static android.os.Process.sendSignal;
111import static android.os.Process.setProcessGroup;
112import static android.os.Process.setThreadPriority;
113import static android.os.Process.setThreadScheduler;
114import static android.os.Process.startWebView;
115import static android.os.Process.zygoteProcess;
116import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
117import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
118import static android.provider.Settings.Global.DEBUG_APP;
119import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
120import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
121import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
122import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
123import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
124import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
125import static android.provider.Settings.System.FONT_SCALE;
126import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
127import static android.text.format.DateUtils.DAY_IN_MILLIS;
128import static android.view.Display.DEFAULT_DISPLAY;
129import static android.view.Display.INVALID_DISPLAY;
130import static com.android.internal.util.XmlUtils.readBooleanAttribute;
131import static com.android.internal.util.XmlUtils.readIntAttribute;
132import static com.android.internal.util.XmlUtils.readLongAttribute;
133import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
134import static com.android.internal.util.XmlUtils.writeIntAttribute;
135import static com.android.internal.util.XmlUtils.writeLongAttribute;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
141import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
142import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
143import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
144import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
145import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
146import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
147import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
148import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
149import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
150import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
151import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
152import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
153import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
154import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
155import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
156import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
157import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
158import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
159import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
160import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
161import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
162import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
163import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
164import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
165import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
166import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
167import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
168import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
169import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
170import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
171import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
172import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
173import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
174import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
175import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
176import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
177import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
178import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
179import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
180import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
181import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
182import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
183import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
184import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
185import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
186import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
187import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
188import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
189import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
190import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
191import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
192import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
193import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
194import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
195import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
196import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
197import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
198import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
199import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
200import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
201import static com.android.server.am.MemoryStatUtil.hasMemcg;
202import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
203import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
204import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
205import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
206import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
207import static android.view.WindowManager.TRANSIT_NONE;
208import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
209import static android.view.WindowManager.TRANSIT_TASK_OPEN;
210import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
211import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
212import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
213import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
214import static org.xmlpull.v1.XmlPullParser.START_TAG;
215
216import android.Manifest;
217import android.Manifest.permission;
218import android.annotation.NonNull;
219import android.annotation.Nullable;
220import android.annotation.UserIdInt;
221import android.app.Activity;
222import android.app.ActivityManager;
223import android.app.ActivityManager.RunningTaskInfo;
224import android.app.ActivityManager.StackInfo;
225import android.app.ActivityManager.TaskSnapshot;
226import android.app.ActivityManagerInternal;
227import android.app.ActivityManagerInternal.ScreenObserver;
228import android.app.ActivityManagerInternal.SleepToken;
229import android.app.ActivityManagerProto;
230import android.app.ActivityOptions;
231import android.app.ActivityThread;
232import android.app.AlertDialog;
233import android.app.AppGlobals;
234import android.app.AppOpsManager;
235import android.app.ApplicationErrorReport;
236import android.app.ApplicationThreadConstants;
237import android.app.BroadcastOptions;
238import android.app.ContentProviderHolder;
239import android.app.Dialog;
240import android.app.GrantedUriPermission;
241import android.app.IActivityController;
242import android.app.IActivityManager;
243import android.app.IApplicationThread;
244import android.app.IAssistDataReceiver;
245import android.app.IInstrumentationWatcher;
246import android.app.INotificationManager;
247import android.app.IProcessObserver;
248import android.app.IServiceConnection;
249import android.app.IStopUserCallback;
250import android.app.ITaskStackListener;
251import android.app.IUiAutomationConnection;
252import android.app.IUidObserver;
253import android.app.IUserSwitchObserver;
254import android.app.Instrumentation;
255import android.app.Notification;
256import android.app.NotificationManager;
257import android.app.PendingIntent;
258import android.app.PictureInPictureParams;
259import android.app.ProcessMemoryState;
260import android.app.ProfilerInfo;
261import android.app.RemoteAction;
262import android.app.WaitResult;
263import android.app.WindowConfiguration.ActivityType;
264import android.app.WindowConfiguration.WindowingMode;
265import android.app.admin.DevicePolicyCache;
266import android.app.assist.AssistContent;
267import android.app.assist.AssistStructure;
268import android.app.backup.IBackupManager;
269import android.app.servertransaction.ConfigurationChangeItem;
270import android.app.usage.UsageEvents;
271import android.app.usage.UsageStatsManagerInternal;
272import android.appwidget.AppWidgetManager;
273import android.content.ActivityNotFoundException;
274import android.content.BroadcastReceiver;
275import android.content.ClipData;
276import android.content.ComponentCallbacks2;
277import android.content.ComponentName;
278import android.content.ContentProvider;
279import android.content.ContentResolver;
280import android.content.Context;
281import android.content.DialogInterface;
282import android.content.IContentProvider;
283import android.content.IIntentReceiver;
284import android.content.IIntentSender;
285import android.content.Intent;
286import android.content.IntentFilter;
287import android.content.pm.ActivityInfo;
288import android.content.pm.ApplicationInfo;
289import android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy;
290import android.content.pm.ConfigurationInfo;
291import android.content.pm.IPackageDataObserver;
292import android.content.pm.IPackageManager;
293import android.content.pm.InstrumentationInfo;
294import android.content.pm.PackageInfo;
295import android.content.pm.PackageManager;
296import android.content.pm.PackageManager.NameNotFoundException;
297import android.content.pm.PackageManagerInternal;
298import android.content.pm.ParceledListSlice;
299import android.content.pm.PathPermission;
300import android.content.pm.PermissionInfo;
301import android.content.pm.ProviderInfo;
302import android.content.pm.ResolveInfo;
303import android.content.pm.SELinuxUtil;
304import android.content.pm.ServiceInfo;
305import android.content.pm.UserInfo;
306import android.content.res.CompatibilityInfo;
307import android.content.res.Configuration;
308import android.content.res.Resources;
309import android.database.ContentObserver;
310import android.graphics.Bitmap;
311import android.graphics.Point;
312import android.graphics.Rect;
313import android.hardware.display.DisplayManagerInternal;
314import android.location.LocationManager;
315import android.media.audiofx.AudioEffect;
316import android.metrics.LogMaker;
317import android.net.Proxy;
318import android.net.ProxyInfo;
319import android.net.Uri;
320import android.os.BatteryStats;
321import android.os.Binder;
322import android.os.Build;
323import android.os.Bundle;
324import android.os.Debug;
325import android.os.DropBoxManager;
326import android.os.Environment;
327import android.os.FactoryTest;
328import android.os.FileObserver;
329import android.os.FileUtils;
330import android.os.Handler;
331import android.os.IBinder;
332import android.os.IDeviceIdentifiersPolicyService;
333import android.os.IPermissionController;
334import android.os.IProcessInfoService;
335import android.os.IProgressListener;
336import android.os.LocaleList;
337import android.os.Looper;
338import android.os.Message;
339import android.os.Parcel;
340import android.os.ParcelFileDescriptor;
341import android.os.PersistableBundle;
342import android.os.PowerManager;
343import android.os.PowerManager.ServiceType;
344import android.os.PowerManagerInternal;
345import android.os.Process;
346import android.os.RemoteCallbackList;
347import android.os.RemoteException;
348import android.os.ResultReceiver;
349import android.os.ServiceManager;
350import android.os.ShellCallback;
351import android.os.StrictMode;
352import android.os.SystemClock;
353import android.os.SystemProperties;
354import android.os.Trace;
355import android.os.TransactionTooLargeException;
356import android.os.UpdateLock;
357import android.os.UserHandle;
358import android.os.UserManager;
359import android.os.WorkSource;
360import android.os.storage.IStorageManager;
361import android.os.storage.StorageManager;
362import android.os.storage.StorageManagerInternal;
363import android.provider.Downloads;
364import android.provider.Settings;
365import android.service.voice.IVoiceInteractionSession;
366import android.service.voice.VoiceInteractionManagerInternal;
367import android.telecom.TelecomManager;
368import android.text.TextUtils;
369import android.text.format.DateUtils;
370import android.text.format.Time;
371import android.text.style.SuggestionSpan;
372import android.util.ArrayMap;
373import android.util.ArraySet;
374import android.util.AtomicFile;
375import android.util.DebugUtils;
376import android.util.EventLog;
377import android.util.Log;
378import android.util.LongSparseArray;
379import android.util.Pair;
380import android.util.PrintWriterPrinter;
381import android.util.Slog;
382import android.util.SparseArray;
383import android.util.SparseIntArray;
384import android.util.StatsLog;
385import android.util.TimeUtils;
386import android.util.TimingsTraceLog;
387import android.util.Xml;
388import android.util.proto.ProtoOutputStream;
389import android.util.proto.ProtoUtils;
390import android.view.Gravity;
391import android.view.IRecentsAnimationRunner;
392import android.view.LayoutInflater;
393import android.view.RemoteAnimationAdapter;
394import android.view.RemoteAnimationDefinition;
395import android.view.View;
396import android.view.WindowManager;
397import android.view.autofill.AutofillManagerInternal;
398
399import com.android.internal.R;
400import com.android.internal.annotations.GuardedBy;
401import com.android.internal.annotations.VisibleForTesting;
402import com.android.internal.app.AssistUtils;
403import com.android.internal.app.DumpHeapActivity;
404import com.android.internal.app.IAppOpsCallback;
405import com.android.internal.app.IAppOpsService;
406import com.android.internal.app.IVoiceInteractor;
407import com.android.internal.app.ProcessMap;
408import com.android.internal.app.SystemUserHomeActivity;
409import com.android.internal.app.procstats.ProcessStats;
410import com.android.internal.logging.MetricsLogger;
411import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
412import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
413import com.android.internal.notification.SystemNotificationChannels;
414import com.android.internal.os.BackgroundThread;
415import com.android.internal.os.BatteryStatsImpl;
416import com.android.internal.os.BinderInternal;
417import com.android.internal.os.logging.MetricsLoggerWrapper;
418import com.android.internal.os.ByteTransferPipe;
419import com.android.internal.os.IResultReceiver;
420import com.android.internal.os.ProcessCpuTracker;
421import com.android.internal.os.TransferPipe;
422import com.android.internal.os.Zygote;
423import com.android.internal.policy.IKeyguardDismissCallback;
424import com.android.internal.policy.KeyguardDismissCallback;
425import com.android.internal.telephony.TelephonyIntents;
426import com.android.internal.util.ArrayUtils;
427import com.android.internal.util.DumpUtils;
428import com.android.internal.util.FastPrintWriter;
429import com.android.internal.util.FastXmlSerializer;
430import com.android.internal.util.MemInfoReader;
431import com.android.internal.util.Preconditions;
432import com.android.server.AlarmManagerInternal;
433import com.android.server.AppOpsService;
434import com.android.server.AttributeCache;
435import com.android.server.DeviceIdleController;
436import com.android.server.IntentResolver;
437import com.android.server.IoThread;
438import com.android.server.LocalServices;
439import com.android.server.LockGuard;
440import com.android.server.NetworkManagementInternal;
441import com.android.server.RescueParty;
442import com.android.server.ServiceThread;
443import com.android.server.SystemConfig;
444import com.android.server.SystemService;
445import com.android.server.SystemServiceManager;
446import com.android.server.ThreadPriorityBooster;
447import com.android.server.Watchdog;
448import com.android.server.am.ActivityStack.ActivityState;
449import com.android.server.am.MemoryStatUtil.MemoryStat;
450import com.android.server.am.ActivityManagerServiceProto;
451import com.android.server.am.ActivityManagerServiceDumpActivitiesProto;
452import com.android.server.am.ActivityManagerServiceDumpBroadcastsProto;
453import com.android.server.am.ActivityManagerServiceDumpProcessesProto;
454import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
455import com.android.server.am.ActivityManagerServiceDumpServicesProto;
456import com.android.server.am.GrantUriProto;
457import com.android.server.am.ImportanceTokenProto;
458import com.android.server.am.MemInfoDumpProto;
459import com.android.server.am.NeededUriGrantsProto;
460import com.android.server.am.ProcessOomProto;
461import com.android.server.am.ProcessToGcProto;
462import com.android.server.am.StickyBroadcastProto;
463import com.android.server.firewall.IntentFirewall;
464import com.android.server.job.JobSchedulerInternal;
465import com.android.server.pm.Installer;
466import com.android.server.pm.Installer.InstallerException;
467import com.android.server.utils.PriorityDump;
468import com.android.server.vr.VrManagerInternal;
469import com.android.server.wm.PinnedStackWindowController;
470import com.android.server.wm.WindowManagerService;
471
472import dalvik.system.VMRuntime;
473
474import libcore.io.IoUtils;
475import libcore.util.EmptyArray;
476
477import com.google.android.collect.Lists;
478import com.google.android.collect.Maps;
479
480import org.xmlpull.v1.XmlPullParser;
481import org.xmlpull.v1.XmlPullParserException;
482import org.xmlpull.v1.XmlSerializer;
483
484import java.io.File;
485import java.io.FileDescriptor;
486import java.io.FileInputStream;
487import java.io.FileNotFoundException;
488import java.io.FileOutputStream;
489import java.io.IOException;
490import java.io.InputStreamReader;
491import java.io.PrintWriter;
492import java.io.StringWriter;
493import java.io.UnsupportedEncodingException;
494import java.lang.ref.WeakReference;
495import java.nio.charset.StandardCharsets;
496import java.text.DateFormat;
497import java.text.SimpleDateFormat;
498import java.util.ArrayList;
499import java.util.Arrays;
500import java.util.Collections;
501import java.util.Comparator;
502import java.util.Date;
503import java.util.HashMap;
504import java.util.HashSet;
505import java.util.Iterator;
506import java.util.List;
507import java.util.Locale;
508import java.util.Map;
509import java.util.Objects;
510import java.util.Set;
511import java.util.concurrent.CountDownLatch;
512import java.util.concurrent.Executor;
513import java.util.concurrent.atomic.AtomicBoolean;
514import java.util.concurrent.atomic.AtomicLong;
515
516public class ActivityManagerService extends IActivityManager.Stub
517        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
518
519    /**
520     * Priority we boost main thread and RT of top app to.
521     */
522    public static final int TOP_APP_PRIORITY_BOOST = -10;
523
524    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
525    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
526    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
527    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
528    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
529    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
530    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
531    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
532    private static final String TAG_LRU = TAG + POSTFIX_LRU;
533    private static final String TAG_MU = TAG + POSTFIX_MU;
534    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
535    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
536    private static final String TAG_POWER = TAG + POSTFIX_POWER;
537    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
538    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
539    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
540    private static final String TAG_PSS = TAG + POSTFIX_PSS;
541    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
542    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
543    private static final String TAG_STACK = TAG + POSTFIX_STACK;
544    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
545    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
546    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
547    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
548
549    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
550    // here so that while the job scheduler can depend on AMS, the other way around
551    // need not be the case.
552    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
553
554    /** Control over CPU and battery monitoring */
555    // write battery stats every 30 minutes.
556    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
557    static final boolean MONITOR_CPU_USAGE = true;
558    // don't sample cpu less than every 5 seconds.
559    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
560    // wait possibly forever for next cpu sample.
561    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
562    static final boolean MONITOR_THREAD_CPU_USAGE = false;
563
564    // The flags that are set for all calls we make to the package manager.
565    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
566
567    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
568
569    // Maximum number of receivers an app can register.
570    private static final int MAX_RECEIVERS_ALLOWED_PER_APP = 1000;
571
572    // Amount of time after a call to stopAppSwitches() during which we will
573    // prevent further untrusted switches from happening.
574    static final long APP_SWITCH_DELAY_TIME = 5*1000;
575
576    // How long we wait for a launched process to attach to the activity manager
577    // before we decide it's never going to come up for real.
578    static final int PROC_START_TIMEOUT = 10*1000;
579    // How long we wait for an attached process to publish its content providers
580    // before we decide it must be hung.
581    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
582
583    // How long we wait for a launched process to attach to the activity manager
584    // before we decide it's never going to come up for real, when the process was
585    // started with a wrapper for instrumentation (such as Valgrind) because it
586    // could take much longer than usual.
587    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
588
589    // How long we allow a receiver to run before giving up on it.
590    static final int BROADCAST_FG_TIMEOUT = 10*1000;
591    static final int BROADCAST_BG_TIMEOUT = 60*1000;
592
593    // How long we wait until we timeout on key dispatching.
594    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
595
596    // How long we wait until we timeout on key dispatching during instrumentation.
597    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
598
599    // Disable hidden API checks for the newly started instrumentation.
600    // Must be kept in sync with Am.
601    private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
602
603    // How long to wait in getAssistContextExtras for the activity and foreground services
604    // to respond with the result.
605    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
606
607    // How long top wait when going through the modern assist (which doesn't need to block
608    // on getting this result before starting to launch its UI).
609    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
610
611    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
612    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
613
614    // Maximum number of persisted Uri grants a package is allowed
615    static final int MAX_PERSISTED_URI_GRANTS = 128;
616
617    static final int MY_PID = myPid();
618
619    static final String[] EMPTY_STRING_ARRAY = new String[0];
620
621    // How many bytes to write into the dropbox log before truncating
622    static final int DROPBOX_MAX_SIZE = 192 * 1024;
623    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
624    // as one line, but close enough for now.
625    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
626
627    /** If a UID observer takes more than this long, send a WTF. */
628    private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20;
629
630    // Access modes for handleIncomingUser.
631    static final int ALLOW_NON_FULL = 0;
632    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
633    static final int ALLOW_FULL_ONLY = 2;
634
635    // Necessary ApplicationInfo flags to mark an app as persistent
636    private static final int PERSISTENT_MASK =
637            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
638
639    // Intent sent when remote bugreport collection has been completed
640    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
641            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
642
643    // Used to indicate that an app transition should be animated.
644    static final boolean ANIMATE = true;
645
646    // Determines whether to take full screen screenshots
647    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
648
649    /**
650     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
651     */
652    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
653
654    /**
655     * State indicating that there is no need for any blocking for network.
656     */
657    @VisibleForTesting
658    static final int NETWORK_STATE_NO_CHANGE = 0;
659
660    /**
661     * State indicating that the main thread needs to be informed about the network wait.
662     */
663    @VisibleForTesting
664    static final int NETWORK_STATE_BLOCK = 1;
665
666    /**
667     * State indicating that any threads waiting for network state to get updated can be unblocked.
668     */
669    @VisibleForTesting
670    static final int NETWORK_STATE_UNBLOCK = 2;
671
672    // Max character limit for a notification title. If the notification title is larger than this
673    // the notification will not be legible to the user.
674    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
675
676    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
677
678    /** All system services */
679    SystemServiceManager mSystemServiceManager;
680
681    // Wrapper around VoiceInteractionServiceManager
682    private AssistUtils mAssistUtils;
683
684    // Keeps track of the active voice interaction service component, notified from
685    // VoiceInteractionManagerService
686    ComponentName mActiveVoiceInteractionServiceComponent;
687
688    private Installer mInstaller;
689
690    /** Run all ActivityStacks through this */
691    final ActivityStackSupervisor mStackSupervisor;
692    private final KeyguardController mKeyguardController;
693
694    private final ActivityStartController mActivityStartController;
695
696    private final ClientLifecycleManager mLifecycleManager;
697
698    final TaskChangeNotificationController mTaskChangeNotificationController;
699
700    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
701
702    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
703
704    public final IntentFirewall mIntentFirewall;
705
706    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
707    // default action automatically.  Important for devices without direct input
708    // devices.
709    private boolean mShowDialogs = true;
710
711    private final VrController mVrController;
712
713    // VR Vr2d Display Id.
714    int mVr2dDisplayId = INVALID_DISPLAY;
715
716    // Whether we should use SCHED_FIFO for UI and RenderThreads.
717    private boolean mUseFifoUiScheduling = false;
718
719    private static final String SYSUI_COMPONENT_NAME = "com.android.systemui/.SystemUIService";
720
721    BroadcastQueue mFgBroadcastQueue;
722    BroadcastQueue mBgBroadcastQueue;
723    // Convenient for easy iteration over the queues. Foreground is first
724    // so that dispatch of foreground broadcasts gets precedence.
725    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
726
727    BroadcastStats mLastBroadcastStats;
728    BroadcastStats mCurBroadcastStats;
729
730    BroadcastQueue broadcastQueueForIntent(Intent intent) {
731        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
732        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
733                "Broadcast intent " + intent + " on "
734                + (isFg ? "foreground" : "background") + " queue");
735        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
736    }
737
738    /**
739     * The last resumed activity. This is identical to the current resumed activity most
740     * of the time but could be different when we're pausing one activity before we resume
741     * another activity.
742     */
743    private ActivityRecord mLastResumedActivity;
744
745    /**
746     * The activity that is currently being traced as the active resumed activity.
747     *
748     * @see #updateResumedAppTrace
749     */
750    private @Nullable ActivityRecord mTracedResumedActivity;
751
752    /**
753     * If non-null, we are tracking the time the user spends in the currently focused app.
754     */
755    private AppTimeTracker mCurAppTimeTracker;
756
757    /**
758     * List of intents that were used to start the most recent tasks.
759     */
760    private final RecentTasks mRecentTasks;
761
762    /**
763     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
764     */
765    String mDeviceOwnerName;
766
767    /**
768     * The controller for all operations related to locktask.
769     */
770    private final LockTaskController mLockTaskController;
771
772    final UserController mUserController;
773
774    /**
775     * Packages that are being allowed to perform unrestricted app switches.  Mapping is
776     * User -> Type -> uid.
777     */
778    final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
779
780    final AppErrors mAppErrors;
781
782    final AppWarnings mAppWarnings;
783
784    /**
785     * Dump of the activity state at the time of the last ANR. Cleared after
786     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
787     */
788    String mLastANRState;
789
790    /**
791     * Indicates the maximum time spent waiting for the network rules to get updated.
792     */
793    @VisibleForTesting
794    long mWaitForNetworkTimeoutMs;
795
796    /** Total # of UID change events dispatched, shown in dumpsys. */
797    int mUidChangeDispatchCount;
798
799    /**
800     * Helper class which strips out priority and proto arguments then calls the dump function with
801     * the appropriate arguments. If priority arguments are omitted, function calls the legacy
802     * dump command.
803     * If priority arguments are omitted all sections are dumped, otherwise sections are dumped
804     * according to their priority.
805     */
806    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
807        @Override
808        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
809                boolean asProto) {
810            if (asProto) return;
811            doDump(fd, pw, new String[]{"activities"}, asProto);
812            doDump(fd, pw, new String[]{"service", SYSUI_COMPONENT_NAME}, asProto);
813        }
814
815        @Override
816        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
817            doDump(fd, pw, new String[]{"-a", "--normal-priority"}, asProto);
818        }
819
820        @Override
821        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
822            doDump(fd, pw, args, asProto);
823        }
824    };
825
826    public boolean canShowErrorDialogs() {
827        return mShowDialogs && !mSleeping && !mShuttingDown
828                && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
829                && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
830                        mUserController.getCurrentUserId())
831                && !(UserManager.isDeviceInDemoMode(mContext)
832                        && mUserController.getCurrentUser().isDemo());
833    }
834
835    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
836            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
837
838    static void boostPriorityForLockedSection() {
839        sThreadPriorityBooster.boost();
840    }
841
842    static void resetPriorityAfterLockedSection() {
843        sThreadPriorityBooster.reset();
844    }
845
846    public class PendingAssistExtras extends Binder implements Runnable {
847        public final ActivityRecord activity;
848        public boolean isHome;
849        public final Bundle extras;
850        public final Intent intent;
851        public final String hint;
852        public final IAssistDataReceiver receiver;
853        public final int userHandle;
854        public boolean haveResult = false;
855        public Bundle result = null;
856        public AssistStructure structure = null;
857        public AssistContent content = null;
858        public Bundle receiverExtras;
859
860        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
861                String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
862                int _userHandle) {
863            activity = _activity;
864            extras = _extras;
865            intent = _intent;
866            hint = _hint;
867            receiver = _receiver;
868            receiverExtras = _receiverExtras;
869            userHandle = _userHandle;
870        }
871
872        @Override
873        public void run() {
874            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
875            synchronized (this) {
876                haveResult = true;
877                notifyAll();
878            }
879            pendingAssistExtrasTimedOut(this);
880        }
881    }
882
883    final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
884
885    /**
886     * Process management.
887     */
888    final ProcessList mProcessList = new ProcessList();
889
890    /**
891     * All of the applications we currently have running organized by name.
892     * The keys are strings of the application package name (as
893     * returned by the package manager), and the keys are ApplicationRecord
894     * objects.
895     */
896    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
897
898    /**
899     * Tracking long-term execution of processes to look for abuse and other
900     * bad app behavior.
901     */
902    final ProcessStatsService mProcessStats;
903
904    /**
905     * The currently running isolated processes.
906     */
907    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
908
909    /**
910     * Counter for assigning isolated process uids, to avoid frequently reusing the
911     * same ones.
912     */
913    int mNextIsolatedProcessUid = 0;
914
915    /**
916     * The currently running heavy-weight process, if any.
917     */
918    ProcessRecord mHeavyWeightProcess = null;
919
920    /**
921     * Non-persistent appId whitelist for background restrictions
922     */
923    int[] mBackgroundAppIdWhitelist = new int[] {
924            BLUETOOTH_UID
925    };
926
927    /**
928     * Broadcast actions that will always be deliverable to unlaunched/background apps
929     */
930    ArraySet<String> mBackgroundLaunchBroadcasts;
931
932    /**
933     * All of the processes we currently have running organized by pid.
934     * The keys are the pid running the application.
935     *
936     * <p>NOTE: This object is protected by its own lock, NOT the global
937     * activity manager lock!
938     */
939    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
940
941    /**
942     * All of the processes that have been forced to be important.  The key
943     * is the pid of the caller who requested it (we hold a death
944     * link on it).
945     */
946    abstract class ImportanceToken implements IBinder.DeathRecipient {
947        final int pid;
948        final IBinder token;
949        final String reason;
950
951        ImportanceToken(int _pid, IBinder _token, String _reason) {
952            pid = _pid;
953            token = _token;
954            reason = _reason;
955        }
956
957        @Override
958        public String toString() {
959            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
960                    + " " + reason + " " + pid + " " + token + " }";
961        }
962
963        void writeToProto(ProtoOutputStream proto, long fieldId) {
964            final long pToken = proto.start(fieldId);
965            proto.write(ImportanceTokenProto.PID, pid);
966            if (token != null) {
967                proto.write(ImportanceTokenProto.TOKEN, token.toString());
968            }
969            proto.write(ImportanceTokenProto.REASON, reason);
970            proto.end(pToken);
971        }
972    }
973    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
974
975    /**
976     * List of records for processes that someone had tried to start before the
977     * system was ready.  We don't start them at that point, but ensure they
978     * are started by the time booting is complete.
979     */
980    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
981
982    /**
983     * List of persistent applications that are in the process
984     * of being started.
985     */
986    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
987
988    /**
989     * Processes that are being forcibly torn down.
990     */
991    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
992
993    /**
994     * List of running applications, sorted by recent usage.
995     * The first entry in the list is the least recently used.
996     */
997    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
998
999    /**
1000     * Where in mLruProcesses that the processes hosting activities start.
1001     */
1002    int mLruProcessActivityStart = 0;
1003
1004    /**
1005     * Where in mLruProcesses that the processes hosting services start.
1006     * This is after (lower index) than mLruProcessesActivityStart.
1007     */
1008    int mLruProcessServiceStart = 0;
1009
1010    /**
1011     * List of processes that should gc as soon as things are idle.
1012     */
1013    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
1014
1015    /**
1016     * Processes we want to collect PSS data from.
1017     */
1018    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
1019
1020    private boolean mBinderTransactionTrackingEnabled = false;
1021
1022    /**
1023     * Last time we requested PSS data of all processes.
1024     */
1025    long mLastFullPssTime = SystemClock.uptimeMillis();
1026
1027    /**
1028     * If set, the next time we collect PSS data we should do a full collection
1029     * with data from native processes and the kernel.
1030     */
1031    boolean mFullPssPending = false;
1032
1033    /**
1034     * This is the process holding what we currently consider to be
1035     * the "home" activity.
1036     */
1037    ProcessRecord mHomeProcess;
1038
1039    /**
1040     * This is the process holding the activity the user last visited that
1041     * is in a different process from the one they are currently in.
1042     */
1043    ProcessRecord mPreviousProcess;
1044
1045    /**
1046     * The time at which the previous process was last visible.
1047     */
1048    long mPreviousProcessVisibleTime;
1049
1050    /**
1051     * Track all uids that have actively running processes.
1052     */
1053    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
1054
1055    /**
1056     * This is for verifying the UID report flow.
1057     */
1058    static final boolean VALIDATE_UID_STATES = true;
1059    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
1060
1061    /**
1062     * Packages that the user has asked to have run in screen size
1063     * compatibility mode instead of filling the screen.
1064     */
1065    final CompatModePackages mCompatModePackages;
1066
1067    /**
1068     * Set of IntentSenderRecord objects that are currently active.
1069     */
1070    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1071            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1072
1073    /**
1074     * Fingerprints (hashCode()) of stack traces that we've
1075     * already logged DropBox entries for.  Guarded by itself.  If
1076     * something (rogue user app) forces this over
1077     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1078     */
1079    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1080    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1081
1082    /**
1083     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1084     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1085     */
1086    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1087
1088    /**
1089     * Resolver for broadcast intents to registered receivers.
1090     * Holds BroadcastFilter (subclass of IntentFilter).
1091     */
1092    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1093            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1094        @Override
1095        protected boolean allowFilterResult(
1096                BroadcastFilter filter, List<BroadcastFilter> dest) {
1097            IBinder target = filter.receiverList.receiver.asBinder();
1098            for (int i = dest.size() - 1; i >= 0; i--) {
1099                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1100                    return false;
1101                }
1102            }
1103            return true;
1104        }
1105
1106        @Override
1107        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1108            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1109                    || userId == filter.owningUserId) {
1110                return super.newResult(filter, match, userId);
1111            }
1112            return null;
1113        }
1114
1115        @Override
1116        protected BroadcastFilter[] newArray(int size) {
1117            return new BroadcastFilter[size];
1118        }
1119
1120        @Override
1121        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1122            return packageName.equals(filter.packageName);
1123        }
1124    };
1125
1126    /**
1127     * State of all active sticky broadcasts per user.  Keys are the action of the
1128     * sticky Intent, values are an ArrayList of all broadcasted intents with
1129     * that action (which should usually be one).  The SparseArray is keyed
1130     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1131     * for stickies that are sent to all users.
1132     */
1133    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1134            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1135
1136    final ActiveServices mServices;
1137
1138    final static class Association {
1139        final int mSourceUid;
1140        final String mSourceProcess;
1141        final int mTargetUid;
1142        final ComponentName mTargetComponent;
1143        final String mTargetProcess;
1144
1145        int mCount;
1146        long mTime;
1147
1148        int mNesting;
1149        long mStartTime;
1150
1151        // states of the source process when the bind occurred.
1152        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1153        long mLastStateUptime;
1154        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1155                - ActivityManager.MIN_PROCESS_STATE+1];
1156
1157        Association(int sourceUid, String sourceProcess, int targetUid,
1158                ComponentName targetComponent, String targetProcess) {
1159            mSourceUid = sourceUid;
1160            mSourceProcess = sourceProcess;
1161            mTargetUid = targetUid;
1162            mTargetComponent = targetComponent;
1163            mTargetProcess = targetProcess;
1164        }
1165    }
1166
1167    /**
1168     * When service association tracking is enabled, this is all of the associations we
1169     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1170     * -> association data.
1171     */
1172    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1173            mAssociations = new SparseArray<>();
1174    boolean mTrackingAssociations;
1175
1176    /**
1177     * Backup/restore process management
1178     */
1179    String mBackupAppName = null;
1180    BackupRecord mBackupTarget = null;
1181
1182    final ProviderMap mProviderMap;
1183
1184    /**
1185     * List of content providers who have clients waiting for them.  The
1186     * application is currently being launched and the provider will be
1187     * removed from this list once it is published.
1188     */
1189    final ArrayList<ContentProviderRecord> mLaunchingProviders
1190            = new ArrayList<ContentProviderRecord>();
1191
1192    /**
1193     * File storing persisted {@link #mGrantedUriPermissions}.
1194     */
1195    private final AtomicFile mGrantFile;
1196
1197    /** XML constants used in {@link #mGrantFile} */
1198    private static final String TAG_URI_GRANTS = "uri-grants";
1199    private static final String TAG_URI_GRANT = "uri-grant";
1200    private static final String ATTR_USER_HANDLE = "userHandle";
1201    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1202    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1203    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1204    private static final String ATTR_TARGET_PKG = "targetPkg";
1205    private static final String ATTR_URI = "uri";
1206    private static final String ATTR_MODE_FLAGS = "modeFlags";
1207    private static final String ATTR_CREATED_TIME = "createdTime";
1208    private static final String ATTR_PREFIX = "prefix";
1209
1210    /**
1211     * Global set of specific {@link Uri} permissions that have been granted.
1212     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1213     * to {@link UriPermission#uri} to {@link UriPermission}.
1214     */
1215    @GuardedBy("this")
1216    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1217            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1218
1219    public static class GrantUri {
1220        public final int sourceUserId;
1221        public final Uri uri;
1222        public boolean prefix;
1223
1224        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1225            this.sourceUserId = sourceUserId;
1226            this.uri = uri;
1227            this.prefix = prefix;
1228        }
1229
1230        @Override
1231        public int hashCode() {
1232            int hashCode = 1;
1233            hashCode = 31 * hashCode + sourceUserId;
1234            hashCode = 31 * hashCode + uri.hashCode();
1235            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1236            return hashCode;
1237        }
1238
1239        @Override
1240        public boolean equals(Object o) {
1241            if (o instanceof GrantUri) {
1242                GrantUri other = (GrantUri) o;
1243                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1244                        && prefix == other.prefix;
1245            }
1246            return false;
1247        }
1248
1249        @Override
1250        public String toString() {
1251            String result = uri.toString() + " [user " + sourceUserId + "]";
1252            if (prefix) result += " [prefix]";
1253            return result;
1254        }
1255
1256        public String toSafeString() {
1257            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1258            if (prefix) result += " [prefix]";
1259            return result;
1260        }
1261
1262        public void writeToProto(ProtoOutputStream proto, long fieldId) {
1263            long token = proto.start(fieldId);
1264            proto.write(GrantUriProto.URI, uri.toString());
1265            proto.write(GrantUriProto.SOURCE_USER_ID, sourceUserId);
1266            proto.end(token);
1267        }
1268
1269        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1270            if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
1271                return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1272                        ContentProvider.getUriWithoutUserId(uri), false);
1273            } else {
1274                return new GrantUri(defaultSourceUserHandle, uri, false);
1275            }
1276        }
1277    }
1278
1279    boolean mSystemProvidersInstalled;
1280
1281    CoreSettingsObserver mCoreSettingsObserver;
1282
1283    FontScaleSettingObserver mFontScaleSettingObserver;
1284
1285    private final class FontScaleSettingObserver extends ContentObserver {
1286        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1287        private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
1288
1289        public FontScaleSettingObserver() {
1290            super(mHandler);
1291            ContentResolver resolver = mContext.getContentResolver();
1292            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1293            resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
1294                    UserHandle.USER_ALL);
1295        }
1296
1297        @Override
1298        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1299            if (mFontScaleUri.equals(uri)) {
1300                updateFontScaleIfNeeded(userId);
1301            } else if (mHideErrorDialogsUri.equals(uri)) {
1302                synchronized (ActivityManagerService.this) {
1303                    updateShouldShowDialogsLocked(getGlobalConfiguration());
1304                }
1305            }
1306        }
1307    }
1308
1309    DevelopmentSettingsObserver mDevelopmentSettingsObserver;
1310
1311    private final class DevelopmentSettingsObserver extends ContentObserver {
1312        private final Uri mUri = Settings.Global
1313                .getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
1314
1315        private final ComponentName mBugreportStorageProvider = new ComponentName(
1316                "com.android.shell", "com.android.shell.BugreportStorageProvider");
1317
1318        public DevelopmentSettingsObserver() {
1319            super(mHandler);
1320            mContext.getContentResolver().registerContentObserver(mUri, false, this,
1321                    UserHandle.USER_ALL);
1322            // Always kick once to ensure that we match current state
1323            onChange();
1324        }
1325
1326        @Override
1327        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1328            if (mUri.equals(uri)) {
1329                onChange();
1330            }
1331        }
1332
1333        public void onChange() {
1334            final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
1335                    Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, Build.IS_ENG ? 1 : 0) != 0;
1336            mContext.getPackageManager().setComponentEnabledSetting(mBugreportStorageProvider,
1337                    enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1338                            : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
1339                    0);
1340        }
1341    }
1342
1343    /**
1344     * Thread-local storage used to carry caller permissions over through
1345     * indirect content-provider access.
1346     */
1347    private class Identity {
1348        public final IBinder token;
1349        public final int pid;
1350        public final int uid;
1351
1352        Identity(IBinder _token, int _pid, int _uid) {
1353            token = _token;
1354            pid = _pid;
1355            uid = _uid;
1356        }
1357    }
1358
1359    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1360
1361    /**
1362     * All information we have collected about the runtime performance of
1363     * any user id that can impact battery performance.
1364     */
1365    final BatteryStatsService mBatteryStatsService;
1366
1367    /**
1368     * Information about component usage
1369     */
1370    UsageStatsManagerInternal mUsageStatsService;
1371
1372    /**
1373     * Access to DeviceIdleController service.
1374     */
1375    DeviceIdleController.LocalService mLocalDeviceIdleController;
1376
1377    /**
1378     * Set of app ids that are whitelisted for device idle and thus background check.
1379     */
1380    int[] mDeviceIdleWhitelist = new int[0];
1381
1382    /**
1383     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1384     */
1385    int[] mDeviceIdleTempWhitelist = new int[0];
1386
1387    static final class PendingTempWhitelist {
1388        final int targetUid;
1389        final long duration;
1390        final String tag;
1391
1392        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1393            targetUid = _targetUid;
1394            duration = _duration;
1395            tag = _tag;
1396        }
1397
1398        void writeToProto(ProtoOutputStream proto, long fieldId) {
1399            final long token = proto.start(fieldId);
1400            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
1401            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
1402            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TAG, tag);
1403            proto.end(token);
1404        }
1405    }
1406
1407    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1408
1409    /**
1410     * Information about and control over application operations
1411     */
1412    final AppOpsService mAppOpsService;
1413
1414    /** Current sequencing integer of the configuration, for skipping old configurations. */
1415    private int mConfigurationSeq;
1416
1417    /**
1418     * Temp object used when global and/or display override configuration is updated. It is also
1419     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1420     * anyone...
1421     */
1422    private Configuration mTempConfig = new Configuration();
1423
1424    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1425            new UpdateConfigurationResult();
1426    private static final class UpdateConfigurationResult {
1427        // Configuration changes that were updated.
1428        int changes;
1429        // If the activity was relaunched to match the new configuration.
1430        boolean activityRelaunched;
1431
1432        void reset() {
1433            changes = 0;
1434            activityRelaunched = false;
1435        }
1436    }
1437
1438    boolean mSuppressResizeConfigChanges;
1439
1440    /**
1441     * Hardware-reported OpenGLES version.
1442     */
1443    final int GL_ES_VERSION;
1444
1445    /**
1446     * List of initialization arguments to pass to all processes when binding applications to them.
1447     * For example, references to the commonly used services.
1448     */
1449    HashMap<String, IBinder> mAppBindArgs;
1450    HashMap<String, IBinder> mIsolatedAppBindArgs;
1451
1452    /**
1453     * Temporary to avoid allocations.  Protected by main lock.
1454     */
1455    final StringBuilder mStringBuilder = new StringBuilder(256);
1456
1457    /**
1458     * Used to control how we initialize the service.
1459     */
1460    ComponentName mTopComponent;
1461    String mTopAction = Intent.ACTION_MAIN;
1462    String mTopData;
1463
1464    volatile boolean mProcessesReady = false;
1465    volatile boolean mSystemReady = false;
1466    volatile boolean mOnBattery = false;
1467    volatile int mFactoryTest;
1468
1469    @GuardedBy("this") boolean mBooting = false;
1470    @GuardedBy("this") boolean mCallFinishBooting = false;
1471    @GuardedBy("this") boolean mBootAnimationComplete = false;
1472    @GuardedBy("this") boolean mLaunchWarningShown = false;
1473    private @GuardedBy("this") boolean mCheckedForSetup = false;
1474
1475    final Context mContext;
1476
1477    /**
1478     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1479     * change at runtime. Use mContext for non-UI purposes.
1480     */
1481    final Context mUiContext;
1482
1483    /**
1484     * The time at which we will allow normal application switches again,
1485     * after a call to {@link #stopAppSwitches()}.
1486     */
1487    long mAppSwitchesAllowedTime;
1488
1489    /**
1490     * This is set to true after the first switch after mAppSwitchesAllowedTime
1491     * is set; any switches after that will clear the time.
1492     */
1493    boolean mDidAppSwitch;
1494
1495    /**
1496     * Last time (in uptime) at which we checked for power usage.
1497     */
1498    long mLastPowerCheckUptime;
1499
1500    /**
1501     * Set while we are wanting to sleep, to prevent any
1502     * activities from being started/resumed.
1503     *
1504     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1505     *
1506     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1507     * while in the sleep state until there is a pending transition out of sleep, in which case
1508     * mSleeping is set to false, and remains false while awake.
1509     *
1510     * Whether mSleeping can quickly toggled between true/false without the device actually
1511     * display changing states is undefined.
1512     */
1513    private boolean mSleeping = false;
1514
1515    /**
1516     * The process state used for processes that are running the top activities.
1517     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1518     */
1519    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1520
1521    /**
1522     * Set while we are running a voice interaction.  This overrides
1523     * sleeping while it is active.
1524     */
1525    IVoiceInteractionSession mRunningVoice;
1526
1527    /**
1528     * For some direct access we need to power manager.
1529     */
1530    PowerManagerInternal mLocalPowerManager;
1531
1532    /**
1533     * We want to hold a wake lock while running a voice interaction session, since
1534     * this may happen with the screen off and we need to keep the CPU running to
1535     * be able to continue to interact with the user.
1536     */
1537    PowerManager.WakeLock mVoiceWakeLock;
1538
1539    /**
1540     * State of external calls telling us if the device is awake or asleep.
1541     */
1542    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1543
1544    /**
1545     * State of external calls telling us if the device is awake or asleep.
1546     */
1547    private boolean mKeyguardShown = false;
1548
1549    /**
1550     * Set if we are shutting down the system, similar to sleeping.
1551     */
1552    boolean mShuttingDown = false;
1553
1554    /**
1555     * Current sequence id for oom_adj computation traversal.
1556     */
1557    int mAdjSeq = 0;
1558
1559    /**
1560     * Current sequence id for process LRU updating.
1561     */
1562    int mLruSeq = 0;
1563
1564    /**
1565     * Keep track of the non-cached/empty process we last found, to help
1566     * determine how to distribute cached/empty processes next time.
1567     */
1568    int mNumNonCachedProcs = 0;
1569
1570    /**
1571     * Keep track of the number of cached hidden procs, to balance oom adj
1572     * distribution between those and empty procs.
1573     */
1574    int mNumCachedHiddenProcs = 0;
1575
1576    /**
1577     * Keep track of the number of service processes we last found, to
1578     * determine on the next iteration which should be B services.
1579     */
1580    int mNumServiceProcs = 0;
1581    int mNewNumAServiceProcs = 0;
1582    int mNewNumServiceProcs = 0;
1583
1584    /**
1585     * Allow the current computed overall memory level of the system to go down?
1586     * This is set to false when we are killing processes for reasons other than
1587     * memory management, so that the now smaller process list will not be taken as
1588     * an indication that memory is tighter.
1589     */
1590    boolean mAllowLowerMemLevel = false;
1591
1592    /**
1593     * The last computed memory level, for holding when we are in a state that
1594     * processes are going away for other reasons.
1595     */
1596    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1597
1598    /**
1599     * The last total number of process we have, to determine if changes actually look
1600     * like a shrinking number of process due to lower RAM.
1601     */
1602    int mLastNumProcesses;
1603
1604    /**
1605     * The uptime of the last time we performed idle maintenance.
1606     */
1607    long mLastIdleTime = SystemClock.uptimeMillis();
1608
1609    /**
1610     * Total time spent with RAM that has been added in the past since the last idle time.
1611     */
1612    long mLowRamTimeSinceLastIdle = 0;
1613
1614    /**
1615     * If RAM is currently low, when that horrible situation started.
1616     */
1617    long mLowRamStartTime = 0;
1618
1619    /**
1620     * For reporting to battery stats the current top application.
1621     */
1622    private String mCurResumedPackage = null;
1623    private int mCurResumedUid = -1;
1624
1625    /**
1626     * For reporting to battery stats the apps currently running foreground
1627     * service.  The ProcessMap is package/uid tuples; each of these contain
1628     * an array of the currently foreground processes.
1629     */
1630    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1631            = new ProcessMap<ArrayList<ProcessRecord>>();
1632
1633    /**
1634     * Set if the systemServer made a call to enterSafeMode.
1635     */
1636    boolean mSafeMode;
1637
1638    /**
1639     * If true, we are running under a test environment so will sample PSS from processes
1640     * much more rapidly to try to collect better data when the tests are rapidly
1641     * running through apps.
1642     */
1643    boolean mTestPssMode = false;
1644
1645    String mDebugApp = null;
1646    boolean mWaitForDebugger = false;
1647    boolean mDebugTransient = false;
1648    String mOrigDebugApp = null;
1649    boolean mOrigWaitForDebugger = false;
1650    boolean mAlwaysFinishActivities = false;
1651    boolean mForceResizableActivities;
1652    /**
1653     * Flag that indicates if multi-window is enabled.
1654     *
1655     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1656     * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1657     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1658     * At least one of the forms of multi-window must be enabled in order for this flag to be
1659     * initialized to 'true'.
1660     *
1661     * @see #mSupportsSplitScreenMultiWindow
1662     * @see #mSupportsFreeformWindowManagement
1663     * @see #mSupportsPictureInPicture
1664     * @see #mSupportsMultiDisplay
1665     */
1666    boolean mSupportsMultiWindow;
1667    boolean mSupportsSplitScreenMultiWindow;
1668    boolean mSupportsFreeformWindowManagement;
1669    boolean mSupportsPictureInPicture;
1670    boolean mSupportsMultiDisplay;
1671    boolean mSupportsLeanbackOnly;
1672    IActivityController mController = null;
1673    boolean mControllerIsAMonkey = false;
1674    String mProfileApp = null;
1675    ProcessRecord mProfileProc = null;
1676    ProfilerInfo mProfilerInfo = null;
1677
1678    /**
1679     * Stores a map of process name -> agent string. When a process is started and mAgentAppMap
1680     * is not null, this map is checked and the mapped agent installed during bind-time. Note:
1681     * A non-null agent in mProfileInfo overrides this.
1682     */
1683    private @Nullable Map<String, String> mAppAgentMap = null;
1684
1685    int mProfileType = 0;
1686    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1687    String mMemWatchDumpProcName;
1688    String mMemWatchDumpFile;
1689    int mMemWatchDumpPid;
1690    int mMemWatchDumpUid;
1691    String mTrackAllocationApp = null;
1692    String mNativeDebuggingApp = null;
1693
1694    final long[] mTmpLong = new long[3];
1695
1696    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1697
1698    /**
1699     * A global counter for generating sequence numbers.
1700     * This value will be used when incrementing sequence numbers in individual uidRecords.
1701     *
1702     * Having a global counter ensures that seq numbers are monotonically increasing for a
1703     * particular uid even when the uidRecord is re-created.
1704     */
1705    @GuardedBy("this")
1706    @VisibleForTesting
1707    long mProcStateSeqCounter = 0;
1708
1709    /**
1710     * A global counter for generating sequence numbers to uniquely identify pending process starts.
1711     */
1712    @GuardedBy("this")
1713    private long mProcStartSeqCounter = 0;
1714
1715    /**
1716     * Contains {@link ProcessRecord} objects for pending process starts.
1717     *
1718     * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
1719     */
1720    @GuardedBy("this")
1721    private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
1722
1723    private final Injector mInjector;
1724
1725    static final class ProcessChangeItem {
1726        static final int CHANGE_ACTIVITIES = 1<<0;
1727        int changes;
1728        int uid;
1729        int pid;
1730        int processState;
1731        boolean foregroundActivities;
1732    }
1733
1734    static final class UidObserverRegistration {
1735        final int uid;
1736        final String pkg;
1737        final int which;
1738        final int cutpoint;
1739
1740        /**
1741         * Total # of callback calls that took more than {@link #SLOW_UID_OBSERVER_THRESHOLD_MS}.
1742         * We show it in dumpsys.
1743         */
1744        int mSlowDispatchCount;
1745
1746        /** Max time it took for each dispatch. */
1747        int mMaxDispatchTime;
1748
1749        final SparseIntArray lastProcStates;
1750
1751        // Please keep the enum lists in sync
1752        private static int[] ORIG_ENUMS = new int[]{
1753                ActivityManager.UID_OBSERVER_IDLE,
1754                ActivityManager.UID_OBSERVER_ACTIVE,
1755                ActivityManager.UID_OBSERVER_GONE,
1756                ActivityManager.UID_OBSERVER_PROCSTATE,
1757        };
1758        private static int[] PROTO_ENUMS = new int[]{
1759                ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
1760                ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
1761                ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
1762                ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
1763        };
1764
1765        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1766            uid = _uid;
1767            pkg = _pkg;
1768            which = _which;
1769            cutpoint = _cutpoint;
1770            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1771                lastProcStates = new SparseIntArray();
1772            } else {
1773                lastProcStates = null;
1774            }
1775        }
1776
1777        void writeToProto(ProtoOutputStream proto, long fieldId) {
1778            final long token = proto.start(fieldId);
1779            proto.write(UidObserverRegistrationProto.UID, uid);
1780            proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
1781            ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
1782                    which, ORIG_ENUMS, PROTO_ENUMS);
1783            proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
1784            if (lastProcStates != null) {
1785                final int NI = lastProcStates.size();
1786                for (int i=0; i<NI; i++) {
1787                    final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
1788                    proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i));
1789                    proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i));
1790                    proto.end(pToken);
1791                }
1792            }
1793            proto.end(token);
1794        }
1795    }
1796
1797    final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1798
1799    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1800    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1801
1802    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1803    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1804
1805    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1806    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1807
1808    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1809    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1810
1811    OomAdjObserver mCurOomAdjObserver;
1812    int mCurOomAdjUid;
1813
1814    interface OomAdjObserver {
1815        void onOomAdjMessage(String msg);
1816    }
1817
1818    /**
1819     * Runtime CPU use collection thread.  This object's lock is used to
1820     * perform synchronization with the thread (notifying it to run).
1821     */
1822    final Thread mProcessCpuThread;
1823
1824    /**
1825     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1826     * Must acquire this object's lock when accessing it.
1827     * NOTE: this lock will be held while doing long operations (trawling
1828     * through all processes in /proc), so it should never be acquired by
1829     * any critical paths such as when holding the main activity manager lock.
1830     */
1831    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1832            MONITOR_THREAD_CPU_USAGE);
1833    final AtomicLong mLastCpuTime = new AtomicLong(0);
1834    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1835    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1836
1837    long mLastWriteTime = 0;
1838
1839    /**
1840     * Used to retain an update lock when the foreground activity is in
1841     * immersive mode.
1842     */
1843    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1844
1845    /**
1846     * Set to true after the system has finished booting.
1847     */
1848    boolean mBooted = false;
1849
1850    WindowManagerService mWindowManager;
1851    final ActivityThread mSystemThread;
1852
1853    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1854        final ProcessRecord mApp;
1855        final int mPid;
1856        final IApplicationThread mAppThread;
1857
1858        AppDeathRecipient(ProcessRecord app, int pid,
1859                IApplicationThread thread) {
1860            if (DEBUG_ALL) Slog.v(
1861                TAG, "New death recipient " + this
1862                + " for thread " + thread.asBinder());
1863            mApp = app;
1864            mPid = pid;
1865            mAppThread = thread;
1866        }
1867
1868        @Override
1869        public void binderDied() {
1870            if (DEBUG_ALL) Slog.v(
1871                TAG, "Death received in " + this
1872                + " for thread " + mAppThread.asBinder());
1873            synchronized(ActivityManagerService.this) {
1874                appDiedLocked(mApp, mPid, mAppThread, true);
1875            }
1876        }
1877    }
1878
1879    static final int SHOW_ERROR_UI_MSG = 1;
1880    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1881    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1882    static final int UPDATE_CONFIGURATION_MSG = 4;
1883    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1884    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1885    static final int SERVICE_TIMEOUT_MSG = 12;
1886    static final int UPDATE_TIME_ZONE = 13;
1887    static final int SHOW_UID_ERROR_UI_MSG = 14;
1888    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1889    static final int PROC_START_TIMEOUT_MSG = 20;
1890    static final int KILL_APPLICATION_MSG = 22;
1891    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1892    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1893    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1894    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1895    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1896    static final int CLEAR_DNS_CACHE_MSG = 28;
1897    static final int UPDATE_HTTP_PROXY_MSG = 29;
1898    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1899    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1900    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1901    static final int REPORT_MEM_USAGE_MSG = 33;
1902    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1903    static final int PERSIST_URI_GRANTS_MSG = 38;
1904    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1905    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1906    static final int FINISH_BOOTING_MSG = 45;
1907    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1908    static final int DISMISS_DIALOG_UI_MSG = 48;
1909    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1910    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1911    static final int DELETE_DUMPHEAP_MSG = 51;
1912    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1913    static final int REPORT_TIME_TRACKER_MSG = 54;
1914    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1915    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1916    static final int IDLE_UIDS_MSG = 58;
1917    static final int LOG_STACK_STATE = 60;
1918    static final int VR_MODE_CHANGE_MSG = 61;
1919    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1920    static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
1921    static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
1922    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1923    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1924    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1925    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1926    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1927
1928    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1929    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1930    static final int FIRST_COMPAT_MODE_MSG = 300;
1931    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1932
1933    static final String SERVICE_RECORD_KEY = "servicerecord";
1934
1935    static ServiceThread sKillThread = null;
1936    static KillHandler sKillHandler = null;
1937
1938    CompatModeDialog mCompatModeDialog;
1939    long mLastMemUsageReportTime = 0;
1940
1941    /**
1942     * Flag whether the current user is a "monkey", i.e. whether
1943     * the UI is driven by a UI automation tool.
1944     */
1945    private boolean mUserIsMonkey;
1946
1947    /** The dimensions of the thumbnails in the Recents UI. */
1948    int mThumbnailWidth;
1949    int mThumbnailHeight;
1950    float mFullscreenThumbnailScale;
1951
1952    final ServiceThread mHandlerThread;
1953    final MainHandler mHandler;
1954    final Handler mUiHandler;
1955    final ServiceThread mProcStartHandlerThread;
1956    final Handler mProcStartHandler;
1957
1958    final ActivityManagerConstants mConstants;
1959
1960    // Encapsulates the global setting "hidden_api_blacklist_exemptions"
1961    final HiddenApiSettings mHiddenApiBlacklist;
1962
1963    PackageManagerInternal mPackageManagerInt;
1964
1965    // VoiceInteraction session ID that changes for each new request except when
1966    // being called for multiwindow assist in a single session.
1967    private int mViSessionId = 1000;
1968
1969    final boolean mPermissionReviewRequired;
1970
1971    /**
1972     * Whether to force background check on all apps (for battery saver) or not.
1973     */
1974    boolean mForceBackgroundCheck;
1975
1976    private static String sTheRealBuildSerial = Build.UNKNOWN;
1977
1978    /**
1979     * Current global configuration information. Contains general settings for the entire system,
1980     * also corresponds to the merged configuration of the default display.
1981     */
1982    Configuration getGlobalConfiguration() {
1983        return mStackSupervisor.getConfiguration();
1984    }
1985
1986    final class KillHandler extends Handler {
1987        static final int KILL_PROCESS_GROUP_MSG = 4000;
1988
1989        public KillHandler(Looper looper) {
1990            super(looper, null, true);
1991        }
1992
1993        @Override
1994        public void handleMessage(Message msg) {
1995            switch (msg.what) {
1996                case KILL_PROCESS_GROUP_MSG:
1997                {
1998                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1999                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
2000                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2001                }
2002                break;
2003
2004                default:
2005                    super.handleMessage(msg);
2006            }
2007        }
2008    }
2009
2010    final class UiHandler extends Handler {
2011        public UiHandler() {
2012            super(com.android.server.UiThread.get().getLooper(), null, true);
2013        }
2014
2015        @Override
2016        public void handleMessage(Message msg) {
2017            switch (msg.what) {
2018            case SHOW_ERROR_UI_MSG: {
2019                mAppErrors.handleShowAppErrorUi(msg);
2020                ensureBootCompleted();
2021            } break;
2022            case SHOW_NOT_RESPONDING_UI_MSG: {
2023                mAppErrors.handleShowAnrUi(msg);
2024                ensureBootCompleted();
2025            } break;
2026            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
2027                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
2028                synchronized (ActivityManagerService.this) {
2029                    ProcessRecord proc = (ProcessRecord) data.get("app");
2030                    if (proc == null) {
2031                        Slog.e(TAG, "App not found when showing strict mode dialog.");
2032                        break;
2033                    }
2034                    if (proc.crashDialog != null) {
2035                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
2036                        return;
2037                    }
2038                    AppErrorResult res = (AppErrorResult) data.get("result");
2039                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
2040                        Dialog d = new StrictModeViolationDialog(mUiContext,
2041                                ActivityManagerService.this, res, proc);
2042                        d.show();
2043                        proc.crashDialog = d;
2044                    } else {
2045                        // The device is asleep, so just pretend that the user
2046                        // saw a crash dialog and hit "force quit".
2047                        res.set(0);
2048                    }
2049                }
2050                ensureBootCompleted();
2051            } break;
2052            case SHOW_FACTORY_ERROR_UI_MSG: {
2053                Dialog d = new FactoryErrorDialog(
2054                        mUiContext, msg.getData().getCharSequence("msg"));
2055                d.show();
2056                ensureBootCompleted();
2057            } break;
2058            case WAIT_FOR_DEBUGGER_UI_MSG: {
2059                synchronized (ActivityManagerService.this) {
2060                    ProcessRecord app = (ProcessRecord)msg.obj;
2061                    if (msg.arg1 != 0) {
2062                        if (!app.waitedForDebugger) {
2063                            Dialog d = new AppWaitingForDebuggerDialog(
2064                                    ActivityManagerService.this,
2065                                    mUiContext, app);
2066                            app.waitDialog = d;
2067                            app.waitedForDebugger = true;
2068                            d.show();
2069                        }
2070                    } else {
2071                        if (app.waitDialog != null) {
2072                            app.waitDialog.dismiss();
2073                            app.waitDialog = null;
2074                        }
2075                    }
2076                }
2077            } break;
2078            case SHOW_UID_ERROR_UI_MSG: {
2079                if (mShowDialogs) {
2080                    AlertDialog d = new BaseErrorDialog(mUiContext);
2081                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2082                    d.setCancelable(false);
2083                    d.setTitle(mUiContext.getText(R.string.android_system_label));
2084                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
2085                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2086                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2087                    d.show();
2088                }
2089            } break;
2090            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
2091                if (mShowDialogs) {
2092                    AlertDialog d = new BaseErrorDialog(mUiContext);
2093                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2094                    d.setCancelable(false);
2095                    d.setTitle(mUiContext.getText(R.string.android_system_label));
2096                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
2097                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2098                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2099                    d.show();
2100                }
2101            } break;
2102            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
2103                synchronized (ActivityManagerService.this) {
2104                    ActivityRecord ar = (ActivityRecord) msg.obj;
2105                    if (mCompatModeDialog != null) {
2106                        if (mCompatModeDialog.mAppInfo.packageName.equals(
2107                                ar.info.applicationInfo.packageName)) {
2108                            return;
2109                        }
2110                        mCompatModeDialog.dismiss();
2111                        mCompatModeDialog = null;
2112                    }
2113                    if (ar != null && false) {
2114                        if (mCompatModePackages.getPackageAskCompatModeLocked(
2115                                ar.packageName)) {
2116                            int mode = mCompatModePackages.computeCompatModeLocked(
2117                                    ar.info.applicationInfo);
2118                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
2119                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
2120                                mCompatModeDialog = new CompatModeDialog(
2121                                        ActivityManagerService.this, mUiContext,
2122                                        ar.info.applicationInfo);
2123                                mCompatModeDialog.show();
2124                            }
2125                        }
2126                    }
2127                }
2128                break;
2129            }
2130            case DISMISS_DIALOG_UI_MSG: {
2131                final Dialog d = (Dialog) msg.obj;
2132                d.dismiss();
2133                break;
2134            }
2135            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
2136                dispatchProcessesChanged();
2137                break;
2138            }
2139            case DISPATCH_PROCESS_DIED_UI_MSG: {
2140                final int pid = msg.arg1;
2141                final int uid = msg.arg2;
2142                dispatchProcessDied(pid, uid);
2143                break;
2144            }
2145            case DISPATCH_UIDS_CHANGED_UI_MSG: {
2146                dispatchUidsChanged();
2147            } break;
2148            case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
2149                dispatchOomAdjObserver((String)msg.obj);
2150            } break;
2151            case PUSH_TEMP_WHITELIST_UI_MSG: {
2152                pushTempWhitelist();
2153            } break;
2154            }
2155        }
2156    }
2157
2158    final class MainHandler extends Handler {
2159        public MainHandler(Looper looper) {
2160            super(looper, null, true);
2161        }
2162
2163        @Override
2164        public void handleMessage(Message msg) {
2165            switch (msg.what) {
2166            case UPDATE_CONFIGURATION_MSG: {
2167                final ContentResolver resolver = mContext.getContentResolver();
2168                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
2169                        msg.arg1);
2170            } break;
2171            case GC_BACKGROUND_PROCESSES_MSG: {
2172                synchronized (ActivityManagerService.this) {
2173                    performAppGcsIfAppropriateLocked();
2174                }
2175            } break;
2176            case SERVICE_TIMEOUT_MSG: {
2177                mServices.serviceTimeout((ProcessRecord)msg.obj);
2178            } break;
2179            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
2180                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
2181            } break;
2182            case SERVICE_FOREGROUND_CRASH_MSG: {
2183                mServices.serviceForegroundCrash(
2184                    (ProcessRecord) msg.obj, msg.getData().getCharSequence(SERVICE_RECORD_KEY));
2185            } break;
2186            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
2187                RemoteCallbackList<IResultReceiver> callbacks
2188                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
2189                int N = callbacks.beginBroadcast();
2190                for (int i = 0; i < N; i++) {
2191                    try {
2192                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
2193                    } catch (RemoteException e) {
2194                    }
2195                }
2196                callbacks.finishBroadcast();
2197            } break;
2198            case UPDATE_TIME_ZONE: {
2199                synchronized (ActivityManagerService.this) {
2200                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2201                        ProcessRecord r = mLruProcesses.get(i);
2202                        if (r.thread != null) {
2203                            try {
2204                                r.thread.updateTimeZone();
2205                            } catch (RemoteException ex) {
2206                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2207                            }
2208                        }
2209                    }
2210                }
2211            } break;
2212            case CLEAR_DNS_CACHE_MSG: {
2213                synchronized (ActivityManagerService.this) {
2214                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2215                        ProcessRecord r = mLruProcesses.get(i);
2216                        if (r.thread != null) {
2217                            try {
2218                                r.thread.clearDnsCache();
2219                            } catch (RemoteException ex) {
2220                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2221                            }
2222                        }
2223                    }
2224                }
2225            } break;
2226            case UPDATE_HTTP_PROXY_MSG: {
2227                ProxyInfo proxy = (ProxyInfo)msg.obj;
2228                String host = "";
2229                String port = "";
2230                String exclList = "";
2231                Uri pacFileUrl = Uri.EMPTY;
2232                if (proxy != null) {
2233                    host = proxy.getHost();
2234                    port = Integer.toString(proxy.getPort());
2235                    exclList = proxy.getExclusionListAsString();
2236                    pacFileUrl = proxy.getPacFileUrl();
2237                }
2238                synchronized (ActivityManagerService.this) {
2239                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2240                        ProcessRecord r = mLruProcesses.get(i);
2241                        // Don't dispatch to isolated processes as they can't access
2242                        // ConnectivityManager and don't have network privileges anyway.
2243                        if (r.thread != null && !r.isolated) {
2244                            try {
2245                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2246                            } catch (RemoteException ex) {
2247                                Slog.w(TAG, "Failed to update http proxy for: " +
2248                                        r.info.processName);
2249                            }
2250                        }
2251                    }
2252                }
2253            } break;
2254            case PROC_START_TIMEOUT_MSG: {
2255                ProcessRecord app = (ProcessRecord)msg.obj;
2256                synchronized (ActivityManagerService.this) {
2257                    processStartTimedOutLocked(app);
2258                }
2259            } break;
2260            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2261                ProcessRecord app = (ProcessRecord)msg.obj;
2262                synchronized (ActivityManagerService.this) {
2263                    processContentProviderPublishTimedOutLocked(app);
2264                }
2265            } break;
2266            case KILL_APPLICATION_MSG: {
2267                synchronized (ActivityManagerService.this) {
2268                    final int appId = msg.arg1;
2269                    final int userId = msg.arg2;
2270                    Bundle bundle = (Bundle)msg.obj;
2271                    String pkg = bundle.getString("pkg");
2272                    String reason = bundle.getString("reason");
2273                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2274                            false, userId, reason);
2275                }
2276            } break;
2277            case FINALIZE_PENDING_INTENT_MSG: {
2278                ((PendingIntentRecord)msg.obj).completeFinalize();
2279            } break;
2280            case POST_HEAVY_NOTIFICATION_MSG: {
2281                INotificationManager inm = NotificationManager.getService();
2282                if (inm == null) {
2283                    return;
2284                }
2285
2286                ActivityRecord root = (ActivityRecord)msg.obj;
2287                ProcessRecord process = root.app;
2288                if (process == null) {
2289                    return;
2290                }
2291
2292                try {
2293                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2294                    String text = mContext.getString(R.string.heavy_weight_notification,
2295                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2296                    Notification notification =
2297                            new Notification.Builder(context,
2298                                    SystemNotificationChannels.HEAVY_WEIGHT_APP)
2299                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2300                            .setWhen(0)
2301                            .setOngoing(true)
2302                            .setTicker(text)
2303                            .setColor(mContext.getColor(
2304                                    com.android.internal.R.color.system_notification_accent_color))
2305                            .setContentTitle(text)
2306                            .setContentText(
2307                                    mContext.getText(R.string.heavy_weight_notification_detail))
2308                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2309                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2310                                    new UserHandle(root.userId)))
2311                            .build();
2312                    try {
2313                        inm.enqueueNotificationWithTag("android", "android", null,
2314                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2315                                notification, root.userId);
2316                    } catch (RuntimeException e) {
2317                        Slog.w(ActivityManagerService.TAG,
2318                                "Error showing notification for heavy-weight app", e);
2319                    } catch (RemoteException e) {
2320                    }
2321                } catch (NameNotFoundException e) {
2322                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2323                }
2324            } break;
2325            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2326                INotificationManager inm = NotificationManager.getService();
2327                if (inm == null) {
2328                    return;
2329                }
2330                try {
2331                    inm.cancelNotificationWithTag("android", null,
2332                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2333                } catch (RuntimeException e) {
2334                    Slog.w(ActivityManagerService.TAG,
2335                            "Error canceling notification for service", e);
2336                } catch (RemoteException e) {
2337                }
2338            } break;
2339            case CHECK_EXCESSIVE_POWER_USE_MSG: {
2340                synchronized (ActivityManagerService.this) {
2341                    checkExcessivePowerUsageLocked();
2342                    removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2343                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2344                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2345                }
2346            } break;
2347            case REPORT_MEM_USAGE_MSG: {
2348                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2349                Thread thread = new Thread() {
2350                    @Override public void run() {
2351                        reportMemUsage(memInfos);
2352                    }
2353                };
2354                thread.start();
2355                break;
2356            }
2357            case IMMERSIVE_MODE_LOCK_MSG: {
2358                final boolean nextState = (msg.arg1 != 0);
2359                if (mUpdateLock.isHeld() != nextState) {
2360                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2361                            "Applying new update lock state '" + nextState
2362                            + "' for " + (ActivityRecord)msg.obj);
2363                    if (nextState) {
2364                        mUpdateLock.acquire();
2365                    } else {
2366                        mUpdateLock.release();
2367                    }
2368                }
2369                break;
2370            }
2371            case PERSIST_URI_GRANTS_MSG: {
2372                writeGrantedUriPermissions();
2373                break;
2374            }
2375            case UPDATE_TIME_PREFERENCE_MSG: {
2376                // The user's time format preference might have changed.
2377                // For convenience we re-use the Intent extra values.
2378                synchronized (ActivityManagerService.this) {
2379                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2380                        ProcessRecord r = mLruProcesses.get(i);
2381                        if (r.thread != null) {
2382                            try {
2383                                r.thread.updateTimePrefs(msg.arg1);
2384                            } catch (RemoteException ex) {
2385                                Slog.w(TAG, "Failed to update preferences for: "
2386                                        + r.info.processName);
2387                            }
2388                        }
2389                    }
2390                }
2391                break;
2392            }
2393            case ENTER_ANIMATION_COMPLETE_MSG: {
2394                synchronized (ActivityManagerService.this) {
2395                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2396                    if (r != null && r.app != null && r.app.thread != null) {
2397                        try {
2398                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2399                        } catch (RemoteException e) {
2400                        }
2401                    }
2402                }
2403                break;
2404            }
2405            case FINISH_BOOTING_MSG: {
2406                if (msg.arg1 != 0) {
2407                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2408                    finishBooting();
2409                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2410                }
2411                if (msg.arg2 != 0) {
2412                    enableScreenAfterBoot();
2413                }
2414                break;
2415            }
2416            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2417                try {
2418                    Locale l = (Locale) msg.obj;
2419                    IBinder service = ServiceManager.getService("mount");
2420                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2421                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2422                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2423                } catch (RemoteException e) {
2424                    Log.e(TAG, "Error storing locale for decryption UI", e);
2425                }
2426                break;
2427            }
2428            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2429                final int uid = msg.arg1;
2430                final byte[] firstPacket = (byte[]) msg.obj;
2431
2432                synchronized (mPidsSelfLocked) {
2433                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2434                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2435                        if (p.uid == uid) {
2436                            try {
2437                                p.thread.notifyCleartextNetwork(firstPacket);
2438                            } catch (RemoteException ignored) {
2439                            }
2440                        }
2441                    }
2442                }
2443                break;
2444            }
2445            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2446                final String procName;
2447                final int uid;
2448                final long memLimit;
2449                final String reportPackage;
2450                synchronized (ActivityManagerService.this) {
2451                    procName = mMemWatchDumpProcName;
2452                    uid = mMemWatchDumpUid;
2453                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2454                    if (val == null) {
2455                        val = mMemWatchProcesses.get(procName, 0);
2456                    }
2457                    if (val != null) {
2458                        memLimit = val.first;
2459                        reportPackage = val.second;
2460                    } else {
2461                        memLimit = 0;
2462                        reportPackage = null;
2463                    }
2464                }
2465                if (procName == null) {
2466                    return;
2467                }
2468
2469                if (DEBUG_PSS) Slog.d(TAG_PSS,
2470                        "Showing dump heap notification from " + procName + "/" + uid);
2471
2472                INotificationManager inm = NotificationManager.getService();
2473                if (inm == null) {
2474                    return;
2475                }
2476
2477                String text = mContext.getString(R.string.dump_heap_notification, procName);
2478
2479
2480                Intent deleteIntent = new Intent();
2481                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2482                Intent intent = new Intent();
2483                intent.setClassName("android", DumpHeapActivity.class.getName());
2484                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2485                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2486                if (reportPackage != null) {
2487                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2488                }
2489                int userId = UserHandle.getUserId(uid);
2490                Notification notification =
2491                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2492                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2493                        .setWhen(0)
2494                        .setOngoing(true)
2495                        .setAutoCancel(true)
2496                        .setTicker(text)
2497                        .setColor(mContext.getColor(
2498                                com.android.internal.R.color.system_notification_accent_color))
2499                        .setContentTitle(text)
2500                        .setContentText(
2501                                mContext.getText(R.string.dump_heap_notification_detail))
2502                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2503                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2504                                new UserHandle(userId)))
2505                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2506                                deleteIntent, 0, UserHandle.SYSTEM))
2507                        .build();
2508
2509                try {
2510                    inm.enqueueNotificationWithTag("android", "android", null,
2511                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2512                            notification, userId);
2513                } catch (RuntimeException e) {
2514                    Slog.w(ActivityManagerService.TAG,
2515                            "Error showing notification for dump heap", e);
2516                } catch (RemoteException e) {
2517                }
2518            } break;
2519            case DELETE_DUMPHEAP_MSG: {
2520                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2521                        null, DumpHeapActivity.JAVA_URI,
2522                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2523                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2524                        UserHandle.myUserId());
2525                synchronized (ActivityManagerService.this) {
2526                    mMemWatchDumpFile = null;
2527                    mMemWatchDumpProcName = null;
2528                    mMemWatchDumpPid = -1;
2529                    mMemWatchDumpUid = -1;
2530                }
2531            } break;
2532            case REPORT_TIME_TRACKER_MSG: {
2533                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2534                tracker.deliverResult(mContext);
2535            } break;
2536            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2537                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2538                try {
2539                    connection.shutdown();
2540                } catch (RemoteException e) {
2541                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2542                }
2543                // Only a UiAutomation can set this flag and now that
2544                // it is finished we make sure it is reset to its default.
2545                mUserIsMonkey = false;
2546            } break;
2547            case IDLE_UIDS_MSG: {
2548                idleUids();
2549            } break;
2550            case VR_MODE_CHANGE_MSG: {
2551                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2552                    return;
2553                }
2554                synchronized (ActivityManagerService.this) {
2555                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2556                    mWindowManager.disableNonVrUi(disableNonVrUi);
2557                    if (disableNonVrUi) {
2558                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2559                        // then remove the pinned stack.
2560                        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2561                    }
2562                }
2563            } break;
2564            case DISPATCH_SCREEN_AWAKE_MSG: {
2565                final boolean isAwake = msg.arg1 != 0;
2566                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2567                    mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2568                }
2569            } break;
2570            case DISPATCH_SCREEN_KEYGUARD_MSG: {
2571                final boolean isShowing = msg.arg1 != 0;
2572                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2573                    mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2574                }
2575            } break;
2576            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2577                synchronized (ActivityManagerService.this) {
2578                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2579                        ProcessRecord r = mLruProcesses.get(i);
2580                        if (r.thread != null) {
2581                            try {
2582                                r.thread.handleTrustStorageUpdate();
2583                            } catch (RemoteException ex) {
2584                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2585                                        r.info.processName);
2586                            }
2587                        }
2588                    }
2589                }
2590            } break;
2591            }
2592        }
2593    };
2594
2595    static final int COLLECT_PSS_BG_MSG = 1;
2596
2597    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2598        @Override
2599        public void handleMessage(Message msg) {
2600            switch (msg.what) {
2601            case COLLECT_PSS_BG_MSG: {
2602                long start = SystemClock.uptimeMillis();
2603                MemInfoReader memInfo = null;
2604                synchronized (ActivityManagerService.this) {
2605                    if (mFullPssPending) {
2606                        mFullPssPending = false;
2607                        memInfo = new MemInfoReader();
2608                    }
2609                }
2610                if (memInfo != null) {
2611                    updateCpuStatsNow();
2612                    long nativeTotalPss = 0;
2613                    final List<ProcessCpuTracker.Stats> stats;
2614                    synchronized (mProcessCpuTracker) {
2615                        stats = mProcessCpuTracker.getStats( (st)-> {
2616                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2617                        });
2618                    }
2619                    final int N = stats.size();
2620                    for (int j = 0; j < N; j++) {
2621                        synchronized (mPidsSelfLocked) {
2622                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2623                                // This is one of our own processes; skip it.
2624                                continue;
2625                            }
2626                        }
2627                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2628                    }
2629                    memInfo.readMemInfo();
2630                    synchronized (ActivityManagerService.this) {
2631                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2632                                + (SystemClock.uptimeMillis()-start) + "ms");
2633                        final long cachedKb = memInfo.getCachedSizeKb();
2634                        final long freeKb = memInfo.getFreeSizeKb();
2635                        final long zramKb = memInfo.getZramTotalSizeKb();
2636                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2637                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2638                                kernelKb*1024, nativeTotalPss*1024);
2639                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2640                                nativeTotalPss);
2641                    }
2642                }
2643
2644                int num = 0;
2645                long[] tmp = new long[3];
2646                do {
2647                    ProcessRecord proc;
2648                    int procState;
2649                    int statType;
2650                    int pid;
2651                    long lastPssTime;
2652                    synchronized (ActivityManagerService.this) {
2653                        if (mPendingPssProcesses.size() <= 0) {
2654                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2655                                    "Collected pss of " + num + " processes in "
2656                                    + (SystemClock.uptimeMillis() - start) + "ms");
2657                            mPendingPssProcesses.clear();
2658                            return;
2659                        }
2660                        proc = mPendingPssProcesses.remove(0);
2661                        procState = proc.pssProcState;
2662                        statType = proc.pssStatType;
2663                        lastPssTime = proc.lastPssTime;
2664                        long now = SystemClock.uptimeMillis();
2665                        if (proc.thread != null && procState == proc.setProcState
2666                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2667                                        < now) {
2668                            pid = proc.pid;
2669                        } else {
2670                            ProcessList.abortNextPssTime(proc.procStateMemTracker);
2671                            if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2672                                    ": still need " +
2673                                    (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE-now) +
2674                                    "ms until safe");
2675                            proc = null;
2676                            pid = 0;
2677                        }
2678                    }
2679                    if (proc != null) {
2680                        long startTime = SystemClock.currentThreadTimeMillis();
2681                        long pss = Debug.getPss(pid, tmp, null);
2682                        long endTime = SystemClock.currentThreadTimeMillis();
2683                        synchronized (ActivityManagerService.this) {
2684                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2685                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2686                                num++;
2687                                ProcessList.commitNextPssTime(proc.procStateMemTracker);
2688                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], tmp[2],
2689                                        statType, endTime-startTime, SystemClock.uptimeMillis());
2690                            } else {
2691                                ProcessList.abortNextPssTime(proc.procStateMemTracker);
2692                                if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2693                                        ": " + (proc.thread == null ? "NO_THREAD " : "") +
2694                                        (proc.pid != pid ? "PID_CHANGED " : "") +
2695                                        " initState=" + procState + " curState=" +
2696                                        proc.setProcState + " " +
2697                                        (proc.lastPssTime != lastPssTime ? "TIME_CHANGED" : ""));
2698                            }
2699                        }
2700                    }
2701                } while (true);
2702            }
2703            }
2704        }
2705    };
2706
2707    public void setSystemProcess() {
2708        try {
2709            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
2710                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
2711            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2712            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
2713                    DUMP_FLAG_PRIORITY_HIGH);
2714            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2715            ServiceManager.addService("dbinfo", new DbBinder(this));
2716            if (MONITOR_CPU_USAGE) {
2717                ServiceManager.addService("cpuinfo", new CpuBinder(this),
2718                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
2719            }
2720            ServiceManager.addService("permission", new PermissionController(this));
2721            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2722
2723            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2724                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2725            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2726
2727            synchronized (this) {
2728                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2729                app.persistent = true;
2730                app.pid = MY_PID;
2731                app.maxAdj = ProcessList.SYSTEM_ADJ;
2732                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2733                synchronized (mPidsSelfLocked) {
2734                    mPidsSelfLocked.put(app.pid, app);
2735                }
2736                updateLruProcessLocked(app, false, null);
2737                updateOomAdjLocked();
2738            }
2739        } catch (PackageManager.NameNotFoundException e) {
2740            throw new RuntimeException(
2741                    "Unable to find android system package", e);
2742        }
2743
2744        // Start watching app ops after we and the package manager are up and running.
2745        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2746                new IAppOpsCallback.Stub() {
2747                    @Override public void opChanged(int op, int uid, String packageName) {
2748                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2749                            if (mAppOpsService.checkOperation(op, uid, packageName)
2750                                    != AppOpsManager.MODE_ALLOWED) {
2751                                runInBackgroundDisabled(uid);
2752                            }
2753                        }
2754                    }
2755                });
2756    }
2757
2758    public void setWindowManager(WindowManagerService wm) {
2759        synchronized (this) {
2760            mWindowManager = wm;
2761            mStackSupervisor.setWindowManager(wm);
2762            mLockTaskController.setWindowManager(wm);
2763        }
2764    }
2765
2766    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2767        mUsageStatsService = usageStatsManager;
2768    }
2769
2770    public void startObservingNativeCrashes() {
2771        final NativeCrashListener ncl = new NativeCrashListener(this);
2772        ncl.start();
2773    }
2774
2775    public IAppOpsService getAppOpsService() {
2776        return mAppOpsService;
2777    }
2778
2779    static class MemBinder extends Binder {
2780        ActivityManagerService mActivityManagerService;
2781        private final PriorityDump.PriorityDumper mPriorityDumper =
2782                new PriorityDump.PriorityDumper() {
2783            @Override
2784            public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args,
2785                    boolean asProto) {
2786                dump(fd, pw, new String[] {"-a"}, asProto);
2787            }
2788
2789            @Override
2790            public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
2791                mActivityManagerService.dumpApplicationMemoryUsage(
2792                        fd, pw, "  ", args, false, null, asProto);
2793            }
2794        };
2795
2796        MemBinder(ActivityManagerService activityManagerService) {
2797            mActivityManagerService = activityManagerService;
2798        }
2799
2800        @Override
2801        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2802            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2803                    "meminfo", pw)) return;
2804            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2805        }
2806    }
2807
2808    static class GraphicsBinder extends Binder {
2809        ActivityManagerService mActivityManagerService;
2810        GraphicsBinder(ActivityManagerService activityManagerService) {
2811            mActivityManagerService = activityManagerService;
2812        }
2813
2814        @Override
2815        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2816            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2817                    "gfxinfo", pw)) return;
2818            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2819        }
2820    }
2821
2822    static class DbBinder extends Binder {
2823        ActivityManagerService mActivityManagerService;
2824        DbBinder(ActivityManagerService activityManagerService) {
2825            mActivityManagerService = activityManagerService;
2826        }
2827
2828        @Override
2829        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2830            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2831                    "dbinfo", pw)) return;
2832            mActivityManagerService.dumpDbInfo(fd, pw, args);
2833        }
2834    }
2835
2836    static class CpuBinder extends Binder {
2837        ActivityManagerService mActivityManagerService;
2838        private final PriorityDump.PriorityDumper mPriorityDumper =
2839                new PriorityDump.PriorityDumper() {
2840            @Override
2841            public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
2842                    boolean asProto) {
2843                if (asProto) return;
2844                if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2845                        "cpuinfo", pw)) return;
2846                synchronized (mActivityManagerService.mProcessCpuTracker) {
2847                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2848                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2849                            SystemClock.uptimeMillis()));
2850                }
2851            }
2852        };
2853
2854        CpuBinder(ActivityManagerService activityManagerService) {
2855            mActivityManagerService = activityManagerService;
2856        }
2857
2858        @Override
2859        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2860            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2861        }
2862    }
2863
2864    public static final class Lifecycle extends SystemService {
2865        private final ActivityManagerService mService;
2866
2867        public Lifecycle(Context context) {
2868            super(context);
2869            mService = new ActivityManagerService(context);
2870        }
2871
2872        @Override
2873        public void onStart() {
2874            mService.start();
2875        }
2876
2877        @Override
2878        public void onBootPhase(int phase) {
2879            if (phase == PHASE_SYSTEM_SERVICES_READY) {
2880                mService.mBatteryStatsService.systemServicesReady();
2881                mService.mServices.systemServicesReady();
2882            }
2883        }
2884
2885        @Override
2886        public void onCleanupUser(int userId) {
2887            mService.mBatteryStatsService.onCleanupUser(userId);
2888        }
2889
2890        public ActivityManagerService getService() {
2891            return mService;
2892        }
2893    }
2894
2895    /**
2896     * Encapsulates global settings related to hidden API enforcement behaviour, including tracking
2897     * the latest value via a content observer.
2898     */
2899    static class HiddenApiSettings extends ContentObserver {
2900
2901        private final Context mContext;
2902        private boolean mBlacklistDisabled;
2903        private String mExemptionsStr;
2904        private List<String> mExemptions = Collections.emptyList();
2905        private int mLogSampleRate = -1;
2906        @HiddenApiEnforcementPolicy private int mPolicyPreP = HIDDEN_API_ENFORCEMENT_DEFAULT;
2907        @HiddenApiEnforcementPolicy private int mPolicyP = HIDDEN_API_ENFORCEMENT_DEFAULT;
2908
2909        public HiddenApiSettings(Handler handler, Context context) {
2910            super(handler);
2911            mContext = context;
2912        }
2913
2914        public void registerObserver() {
2915            mContext.getContentResolver().registerContentObserver(
2916                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS),
2917                    false,
2918                    this);
2919            mContext.getContentResolver().registerContentObserver(
2920                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE),
2921                    false,
2922                    this);
2923            mContext.getContentResolver().registerContentObserver(
2924                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS),
2925                    false,
2926                    this);
2927            mContext.getContentResolver().registerContentObserver(
2928                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_P_APPS),
2929                    false,
2930                    this);
2931            update();
2932        }
2933
2934        private void update() {
2935            String exemptions = Settings.Global.getString(mContext.getContentResolver(),
2936                    Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS);
2937            if (!TextUtils.equals(exemptions, mExemptionsStr)) {
2938                mExemptionsStr = exemptions;
2939                if ("*".equals(exemptions)) {
2940                    mBlacklistDisabled = true;
2941                    mExemptions = Collections.emptyList();
2942                } else {
2943                    mBlacklistDisabled = false;
2944                    mExemptions = TextUtils.isEmpty(exemptions)
2945                            ? Collections.emptyList()
2946                            : Arrays.asList(exemptions.split(","));
2947                }
2948                zygoteProcess.setApiBlacklistExemptions(mExemptions);
2949            }
2950            int logSampleRate = Settings.Global.getInt(mContext.getContentResolver(),
2951                    Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, -1);
2952            if (logSampleRate < 0 || logSampleRate > 0x10000) {
2953                logSampleRate = -1;
2954            }
2955            if (logSampleRate != -1 && logSampleRate != mLogSampleRate) {
2956                mLogSampleRate = logSampleRate;
2957                zygoteProcess.setHiddenApiAccessLogSampleRate(mLogSampleRate);
2958            }
2959            mPolicyPreP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS);
2960            mPolicyP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_P_APPS);
2961        }
2962
2963        private @HiddenApiEnforcementPolicy int getValidEnforcementPolicy(String settingsKey) {
2964            int policy = Settings.Global.getInt(mContext.getContentResolver(), settingsKey,
2965                    ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT);
2966            if (ApplicationInfo.isValidHiddenApiEnforcementPolicy(policy)) {
2967                return policy;
2968            } else {
2969                return ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
2970            }
2971        }
2972
2973        boolean isDisabled() {
2974            return mBlacklistDisabled;
2975        }
2976
2977        @HiddenApiEnforcementPolicy int getPolicyForPrePApps() {
2978            return mPolicyPreP;
2979        }
2980
2981        @HiddenApiEnforcementPolicy int getPolicyForPApps() {
2982            return mPolicyP;
2983        }
2984
2985        public void onChange(boolean selfChange) {
2986            update();
2987        }
2988    }
2989
2990    @VisibleForTesting
2991    public ActivityManagerService(Injector injector) {
2992        mInjector = injector;
2993        mContext = mInjector.getContext();
2994        mUiContext = null;
2995        GL_ES_VERSION = 0;
2996        mActivityStartController = null;
2997        mAppErrors = null;
2998        mAppWarnings = null;
2999        mAppOpsService = mInjector.getAppOpsService(null, null);
3000        mBatteryStatsService = null;
3001        mCompatModePackages = null;
3002        mConstants = null;
3003        mGrantFile = null;
3004        mHandler = null;
3005        mHandlerThread = null;
3006        mIntentFirewall = null;
3007        mKeyguardController = null;
3008        mPermissionReviewRequired = false;
3009        mProcessCpuThread = null;
3010        mProcessStats = null;
3011        mProviderMap = null;
3012        mRecentTasks = null;
3013        mServices = null;
3014        mStackSupervisor = null;
3015        mSystemThread = null;
3016        mTaskChangeNotificationController = null;
3017        mUiHandler = injector.getUiHandler(null);
3018        mUserController = null;
3019        mVrController = null;
3020        mLockTaskController = null;
3021        mLifecycleManager = null;
3022        mProcStartHandlerThread = null;
3023        mProcStartHandler = null;
3024        mHiddenApiBlacklist = null;
3025    }
3026
3027    // Note: This method is invoked on the main thread but may need to attach various
3028    // handlers to other threads.  So take care to be explicit about the looper.
3029    public ActivityManagerService(Context systemContext) {
3030        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
3031        mInjector = new Injector();
3032        mContext = systemContext;
3033
3034        mFactoryTest = FactoryTest.getMode();
3035        mSystemThread = ActivityThread.currentActivityThread();
3036        mUiContext = mSystemThread.getSystemUiContext();
3037
3038        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
3039
3040        mPermissionReviewRequired = mContext.getResources().getBoolean(
3041                com.android.internal.R.bool.config_permissionReviewRequired);
3042
3043        mHandlerThread = new ServiceThread(TAG,
3044                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
3045        mHandlerThread.start();
3046        mHandler = new MainHandler(mHandlerThread.getLooper());
3047        mUiHandler = mInjector.getUiHandler(this);
3048
3049        mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
3050                THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
3051        mProcStartHandlerThread.start();
3052        mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
3053
3054        mConstants = new ActivityManagerConstants(this, mHandler);
3055
3056        /* static; one-time init here */
3057        if (sKillHandler == null) {
3058            sKillThread = new ServiceThread(TAG + ":kill",
3059                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
3060            sKillThread.start();
3061            sKillHandler = new KillHandler(sKillThread.getLooper());
3062        }
3063
3064        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
3065                "foreground", BROADCAST_FG_TIMEOUT, false);
3066        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
3067                "background", BROADCAST_BG_TIMEOUT, true);
3068        mBroadcastQueues[0] = mFgBroadcastQueue;
3069        mBroadcastQueues[1] = mBgBroadcastQueue;
3070
3071        mServices = new ActiveServices(this);
3072        mProviderMap = new ProviderMap(this);
3073        mAppErrors = new AppErrors(mUiContext, this);
3074
3075        File dataDir = Environment.getDataDirectory();
3076        File systemDir = new File(dataDir, "system");
3077        systemDir.mkdirs();
3078
3079        mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
3080
3081        // TODO: Move creation of battery stats service outside of activity manager service.
3082        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
3083        mBatteryStatsService.getActiveStatistics().readLocked();
3084        mBatteryStatsService.scheduleWriteToDisk();
3085        mOnBattery = DEBUG_POWER ? true
3086                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
3087        mBatteryStatsService.getActiveStatistics().setCallback(this);
3088
3089        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
3090
3091        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
3092
3093        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
3094
3095        mUserController = new UserController(this);
3096
3097        mVrController = new VrController(this);
3098
3099        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
3100            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
3101
3102        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
3103            mUseFifoUiScheduling = true;
3104        }
3105
3106        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
3107        mTempConfig.setToDefaults();
3108        mTempConfig.setLocales(LocaleList.getDefault());
3109        mConfigurationSeq = mTempConfig.seq = 1;
3110        mStackSupervisor = createStackSupervisor();
3111        mStackSupervisor.onConfigurationChanged(mTempConfig);
3112        mKeyguardController = mStackSupervisor.getKeyguardController();
3113        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
3114        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
3115        mTaskChangeNotificationController =
3116                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
3117        mActivityStartController = new ActivityStartController(this);
3118        mRecentTasks = createRecentTasks();
3119        mStackSupervisor.setRecentTasks(mRecentTasks);
3120        mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
3121        mLifecycleManager = new ClientLifecycleManager();
3122
3123        mProcessCpuThread = new Thread("CpuTracker") {
3124            @Override
3125            public void run() {
3126                synchronized (mProcessCpuTracker) {
3127                    mProcessCpuInitLatch.countDown();
3128                    mProcessCpuTracker.init();
3129                }
3130                while (true) {
3131                    try {
3132                        try {
3133                            synchronized(this) {
3134                                final long now = SystemClock.uptimeMillis();
3135                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
3136                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
3137                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
3138                                //        + ", write delay=" + nextWriteDelay);
3139                                if (nextWriteDelay < nextCpuDelay) {
3140                                    nextCpuDelay = nextWriteDelay;
3141                                }
3142                                if (nextCpuDelay > 0) {
3143                                    mProcessCpuMutexFree.set(true);
3144                                    this.wait(nextCpuDelay);
3145                                }
3146                            }
3147                        } catch (InterruptedException e) {
3148                        }
3149                        updateCpuStatsNow();
3150                    } catch (Exception e) {
3151                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
3152                    }
3153                }
3154            }
3155        };
3156
3157        mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext);
3158
3159        Watchdog.getInstance().addMonitor(this);
3160        Watchdog.getInstance().addThread(mHandler);
3161
3162        // bind background thread to little cores
3163        // this is expected to fail inside of framework tests because apps can't touch cpusets directly
3164        try {
3165            Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(),
3166                    Process.THREAD_GROUP_BG_NONINTERACTIVE);
3167        } catch (Exception e) {
3168            Slog.w(TAG, "Setting background thread cpuset failed");
3169        }
3170
3171    }
3172
3173    protected ActivityStackSupervisor createStackSupervisor() {
3174        final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
3175        supervisor.initialize();
3176        return supervisor;
3177    }
3178
3179    protected RecentTasks createRecentTasks() {
3180        return new RecentTasks(this, mStackSupervisor);
3181    }
3182
3183    RecentTasks getRecentTasks() {
3184        return mRecentTasks;
3185    }
3186
3187    public void setSystemServiceManager(SystemServiceManager mgr) {
3188        mSystemServiceManager = mgr;
3189    }
3190
3191    public void setInstaller(Installer installer) {
3192        mInstaller = installer;
3193    }
3194
3195    private void start() {
3196        removeAllProcessGroups();
3197        mProcessCpuThread.start();
3198
3199        mBatteryStatsService.publish();
3200        mAppOpsService.publish(mContext);
3201        Slog.d("AppOps", "AppOpsService published");
3202        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
3203        // Wait for the synchronized block started in mProcessCpuThread,
3204        // so that any other acccess to mProcessCpuTracker from main thread
3205        // will be blocked during mProcessCpuTracker initialization.
3206        try {
3207            mProcessCpuInitLatch.await();
3208        } catch (InterruptedException e) {
3209            Slog.wtf(TAG, "Interrupted wait during start", e);
3210            Thread.currentThread().interrupt();
3211            throw new IllegalStateException("Interrupted wait during start");
3212        }
3213    }
3214
3215    void onUserStoppedLocked(int userId) {
3216        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
3217        mAllowAppSwitchUids.remove(userId);
3218    }
3219
3220    public void initPowerManagement() {
3221        mStackSupervisor.initPowerManagement();
3222        mBatteryStatsService.initPowerManagement();
3223        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
3224        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
3225        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
3226        mVoiceWakeLock.setReferenceCounted(false);
3227    }
3228
3229    private ArraySet<String> getBackgroundLaunchBroadcasts() {
3230        if (mBackgroundLaunchBroadcasts == null) {
3231            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
3232        }
3233        return mBackgroundLaunchBroadcasts;
3234    }
3235
3236    @Override
3237    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3238            throws RemoteException {
3239        if (code == SYSPROPS_TRANSACTION) {
3240            // We need to tell all apps about the system property change.
3241            ArrayList<IBinder> procs = new ArrayList<IBinder>();
3242            synchronized(this) {
3243                final int NP = mProcessNames.getMap().size();
3244                for (int ip=0; ip<NP; ip++) {
3245                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
3246                    final int NA = apps.size();
3247                    for (int ia=0; ia<NA; ia++) {
3248                        ProcessRecord app = apps.valueAt(ia);
3249                        if (app.thread != null) {
3250                            procs.add(app.thread.asBinder());
3251                        }
3252                    }
3253                }
3254            }
3255
3256            int N = procs.size();
3257            for (int i=0; i<N; i++) {
3258                Parcel data2 = Parcel.obtain();
3259                try {
3260                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
3261                            Binder.FLAG_ONEWAY);
3262                } catch (RemoteException e) {
3263                }
3264                data2.recycle();
3265            }
3266        }
3267        try {
3268            return super.onTransact(code, data, reply, flags);
3269        } catch (RuntimeException e) {
3270            // The activity manager only throws certain exceptions intentionally, so let's
3271            // log all others.
3272            if (!(e instanceof SecurityException
3273                    || e instanceof IllegalArgumentException
3274                    || e instanceof IllegalStateException)) {
3275                Slog.wtf(TAG, "Activity Manager Crash."
3276                        + " UID:" + Binder.getCallingUid()
3277                        + " PID:" + Binder.getCallingPid()
3278                        + " TRANS:" + code, e);
3279            }
3280            throw e;
3281        }
3282    }
3283
3284    void updateCpuStats() {
3285        final long now = SystemClock.uptimeMillis();
3286        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
3287            return;
3288        }
3289        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
3290            synchronized (mProcessCpuThread) {
3291                mProcessCpuThread.notify();
3292            }
3293        }
3294    }
3295
3296    void updateCpuStatsNow() {
3297        synchronized (mProcessCpuTracker) {
3298            mProcessCpuMutexFree.set(false);
3299            final long now = SystemClock.uptimeMillis();
3300            boolean haveNewCpuStats = false;
3301
3302            if (MONITOR_CPU_USAGE &&
3303                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
3304                mLastCpuTime.set(now);
3305                mProcessCpuTracker.update();
3306                if (mProcessCpuTracker.hasGoodLastStats()) {
3307                    haveNewCpuStats = true;
3308                    //Slog.i(TAG, mProcessCpu.printCurrentState());
3309                    //Slog.i(TAG, "Total CPU usage: "
3310                    //        + mProcessCpu.getTotalCpuPercent() + "%");
3311
3312                    // Slog the cpu usage if the property is set.
3313                    if ("true".equals(SystemProperties.get("events.cpu"))) {
3314                        int user = mProcessCpuTracker.getLastUserTime();
3315                        int system = mProcessCpuTracker.getLastSystemTime();
3316                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
3317                        int irq = mProcessCpuTracker.getLastIrqTime();
3318                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
3319                        int idle = mProcessCpuTracker.getLastIdleTime();
3320
3321                        int total = user + system + iowait + irq + softIrq + idle;
3322                        if (total == 0) total = 1;
3323
3324                        EventLog.writeEvent(EventLogTags.CPU,
3325                                ((user+system+iowait+irq+softIrq) * 100) / total,
3326                                (user * 100) / total,
3327                                (system * 100) / total,
3328                                (iowait * 100) / total,
3329                                (irq * 100) / total,
3330                                (softIrq * 100) / total);
3331                    }
3332                }
3333            }
3334
3335            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3336            synchronized(bstats) {
3337                synchronized(mPidsSelfLocked) {
3338                    if (haveNewCpuStats) {
3339                        if (bstats.startAddingCpuLocked()) {
3340                            int totalUTime = 0;
3341                            int totalSTime = 0;
3342                            final int N = mProcessCpuTracker.countStats();
3343                            for (int i=0; i<N; i++) {
3344                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3345                                if (!st.working) {
3346                                    continue;
3347                                }
3348                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3349                                totalUTime += st.rel_utime;
3350                                totalSTime += st.rel_stime;
3351                                if (pr != null) {
3352                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3353                                    if (ps == null || !ps.isActive()) {
3354                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3355                                                pr.info.uid, pr.processName);
3356                                    }
3357                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3358                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3359                                    if (pr.lastCpuTime == 0) {
3360                                        pr.lastCpuTime = pr.curCpuTime;
3361                                    }
3362                                } else {
3363                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3364                                    if (ps == null || !ps.isActive()) {
3365                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3366                                                bstats.mapUid(st.uid), st.name);
3367                                    }
3368                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3369                                }
3370                            }
3371                            final int userTime = mProcessCpuTracker.getLastUserTime();
3372                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3373                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3374                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3375                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3376                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3377                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3378                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3379                        }
3380                    }
3381                }
3382
3383                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3384                    mLastWriteTime = now;
3385                    mBatteryStatsService.scheduleWriteToDisk();
3386                }
3387            }
3388        }
3389    }
3390
3391    @Override
3392    public void batteryNeedsCpuUpdate() {
3393        updateCpuStatsNow();
3394    }
3395
3396    @Override
3397    public void batteryPowerChanged(boolean onBattery) {
3398        // When plugging in, update the CPU stats first before changing
3399        // the plug state.
3400        updateCpuStatsNow();
3401        synchronized (this) {
3402            synchronized(mPidsSelfLocked) {
3403                mOnBattery = DEBUG_POWER ? true : onBattery;
3404            }
3405        }
3406    }
3407
3408    @Override
3409    public void batterySendBroadcast(Intent intent) {
3410        synchronized (this) {
3411            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3412                    OP_NONE, null, false, false,
3413                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3414        }
3415    }
3416
3417    /**
3418     * Initialize the application bind args. These are passed to each
3419     * process when the bindApplication() IPC is sent to the process. They're
3420     * lazily setup to make sure the services are running when they're asked for.
3421     */
3422    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3423        // Isolated processes won't get this optimization, so that we don't
3424        // violate the rules about which services they have access to.
3425        if (isolated) {
3426            if (mIsolatedAppBindArgs == null) {
3427                mIsolatedAppBindArgs = new HashMap<>();
3428                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3429            }
3430            return mIsolatedAppBindArgs;
3431        }
3432
3433        if (mAppBindArgs == null) {
3434            mAppBindArgs = new HashMap<>();
3435
3436            // Setup the application init args
3437            mAppBindArgs.put("package", ServiceManager.getService("package"));
3438            mAppBindArgs.put("window", ServiceManager.getService("window"));
3439            mAppBindArgs.put(Context.ALARM_SERVICE,
3440                    ServiceManager.getService(Context.ALARM_SERVICE));
3441        }
3442        return mAppBindArgs;
3443    }
3444
3445    /**
3446     * Update AMS states when an activity is resumed. This should only be called by
3447     * {@link ActivityStack#onActivityStateChanged(ActivityRecord, ActivityState, String)} when an
3448     * activity is resumed.
3449     */
3450    @GuardedBy("this")
3451    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3452        final TaskRecord task = r.getTask();
3453        if (task.isActivityTypeStandard()) {
3454            if (mCurAppTimeTracker != r.appTimeTracker) {
3455                // We are switching app tracking.  Complete the current one.
3456                if (mCurAppTimeTracker != null) {
3457                    mCurAppTimeTracker.stop();
3458                    mHandler.obtainMessage(
3459                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3460                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3461                    mCurAppTimeTracker = null;
3462                }
3463                if (r.appTimeTracker != null) {
3464                    mCurAppTimeTracker = r.appTimeTracker;
3465                    startTimeTrackingFocusedActivityLocked();
3466                }
3467            } else {
3468                startTimeTrackingFocusedActivityLocked();
3469            }
3470        } else {
3471            r.appTimeTracker = null;
3472        }
3473        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3474        // TODO: Probably not, because we don't want to resume voice on switching
3475        // back to this activity
3476        if (task.voiceInteractor != null) {
3477            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3478        } else {
3479            finishRunningVoiceLocked();
3480
3481            if (mLastResumedActivity != null) {
3482                final IVoiceInteractionSession session;
3483
3484                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3485                if (lastResumedActivityTask != null
3486                        && lastResumedActivityTask.voiceSession != null) {
3487                    session = lastResumedActivityTask.voiceSession;
3488                } else {
3489                    session = mLastResumedActivity.voiceSession;
3490                }
3491
3492                if (session != null) {
3493                    // We had been in a voice interaction session, but now focused has
3494                    // move to something different.  Just finish the session, we can't
3495                    // return to it and retain the proper state and synchronization with
3496                    // the voice interaction service.
3497                    finishVoiceTask(session);
3498                }
3499            }
3500        }
3501
3502        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3503            mUserController.sendForegroundProfileChanged(r.userId);
3504        }
3505        updateResumedAppTrace(r);
3506        mLastResumedActivity = r;
3507
3508        mWindowManager.setFocusedApp(r.appToken, true);
3509
3510        applyUpdateLockStateLocked(r);
3511        applyUpdateVrModeLocked(r);
3512
3513        EventLogTags.writeAmSetResumedActivity(
3514                r == null ? -1 : r.userId,
3515                r == null ? "NULL" : r.shortComponentName,
3516                reason);
3517    }
3518
3519    private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
3520        if (mTracedResumedActivity != null) {
3521            Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
3522                    constructResumedTraceName(mTracedResumedActivity.packageName), 0);
3523        }
3524        if (resumed != null) {
3525            Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
3526                    constructResumedTraceName(resumed.packageName), 0);
3527        }
3528        mTracedResumedActivity = resumed;
3529    }
3530
3531    private String constructResumedTraceName(String packageName) {
3532        return "focused app: " + packageName;
3533    }
3534
3535    @Override
3536    public void setFocusedStack(int stackId) {
3537        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3538        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3539        final long callingId = Binder.clearCallingIdentity();
3540        try {
3541            synchronized (this) {
3542                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3543                if (stack == null) {
3544                    Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
3545                    return;
3546                }
3547                final ActivityRecord r = stack.topRunningActivityLocked();
3548                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3549                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3550                }
3551            }
3552        } finally {
3553            Binder.restoreCallingIdentity(callingId);
3554        }
3555    }
3556
3557    @Override
3558    public void setFocusedTask(int taskId) {
3559        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3560        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3561        final long callingId = Binder.clearCallingIdentity();
3562        try {
3563            synchronized (this) {
3564                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3565                if (task == null) {
3566                    return;
3567                }
3568                final ActivityRecord r = task.topRunningActivityLocked();
3569                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3570                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3571                }
3572            }
3573        } finally {
3574            Binder.restoreCallingIdentity(callingId);
3575        }
3576    }
3577
3578    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3579    @Override
3580    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3581        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3582                "registerTaskStackListener()");
3583        mTaskChangeNotificationController.registerTaskStackListener(listener);
3584    }
3585
3586    /**
3587     * Unregister a task stack listener so that it stops receiving callbacks.
3588     */
3589    @Override
3590    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3591        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3592                "unregisterTaskStackListener()");
3593         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3594     }
3595
3596    @Override
3597    public void notifyActivityDrawn(IBinder token) {
3598        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3599        synchronized (this) {
3600            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3601            if (r != null) {
3602                r.getStack().notifyActivityDrawnLocked(r);
3603            }
3604        }
3605    }
3606
3607    final void applyUpdateLockStateLocked(ActivityRecord r) {
3608        // Modifications to the UpdateLock state are done on our handler, outside
3609        // the activity manager's locks.  The new state is determined based on the
3610        // state *now* of the relevant activity record.  The object is passed to
3611        // the handler solely for logging detail, not to be consulted/modified.
3612        final boolean nextState = r != null && r.immersive;
3613        mHandler.sendMessage(
3614                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3615    }
3616
3617    final void applyUpdateVrModeLocked(ActivityRecord r) {
3618        // VR apps are expected to run in a main display. If an app is turning on VR for
3619        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3620        // fullscreen stack before enabling VR Mode.
3621        // TODO: The goal of this code is to keep the VR app on the main display. When the
3622        // stack implementation changes in the future, keep in mind that the use of the fullscreen
3623        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3624        // option would be a better choice here.
3625        if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3626            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3627                    + " to main stack for VR");
3628            final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3629                    WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3630            moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3631        }
3632        mHandler.sendMessage(
3633                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3634    }
3635
3636    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3637        Message msg = Message.obtain();
3638        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3639        msg.obj = r.getTask().askedCompatMode ? null : r;
3640        mUiHandler.sendMessage(msg);
3641    }
3642
3643    final AppWarnings getAppWarningsLocked() {
3644        return mAppWarnings;
3645    }
3646
3647    /**
3648     * Shows app warning dialogs, if necessary.
3649     *
3650     * @param r activity record for which the warnings may be displayed
3651     */
3652    final void showAppWarningsIfNeededLocked(ActivityRecord r) {
3653        mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
3654        mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
3655        mAppWarnings.showDeprecatedTargetDialogIfNeeded(r);
3656    }
3657
3658    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3659            String what, Object obj, ProcessRecord srcApp) {
3660        app.lastActivityTime = now;
3661
3662        if (app.activities.size() > 0 || app.recentTasks.size() > 0) {
3663            // Don't want to touch dependent processes that are hosting activities.
3664            return index;
3665        }
3666
3667        int lrui = mLruProcesses.lastIndexOf(app);
3668        if (lrui < 0) {
3669            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3670                    + what + " " + obj + " from " + srcApp);
3671            return index;
3672        }
3673
3674        if (lrui >= index) {
3675            // Don't want to cause this to move dependent processes *back* in the
3676            // list as if they were less frequently used.
3677            return index;
3678        }
3679
3680        if (lrui >= mLruProcessActivityStart) {
3681            // Don't want to touch dependent processes that are hosting activities.
3682            return index;
3683        }
3684
3685        mLruProcesses.remove(lrui);
3686        if (index > 0) {
3687            index--;
3688        }
3689        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3690                + " in LRU list: " + app);
3691        mLruProcesses.add(index, app);
3692        return index;
3693    }
3694
3695    static void killProcessGroup(int uid, int pid) {
3696        if (sKillHandler != null) {
3697            sKillHandler.sendMessage(
3698                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3699        } else {
3700            Slog.w(TAG, "Asked to kill process group before system bringup!");
3701            Process.killProcessGroup(uid, pid);
3702        }
3703    }
3704
3705    final void removeLruProcessLocked(ProcessRecord app) {
3706        int lrui = mLruProcesses.lastIndexOf(app);
3707        if (lrui >= 0) {
3708            if (!app.killed) {
3709                if (app.persistent) {
3710                    Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
3711                } else {
3712                    Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3713                    if (app.pid > 0) {
3714                        killProcessQuiet(app.pid);
3715                        killProcessGroup(app.uid, app.pid);
3716                    } else {
3717                        app.pendingStart = false;
3718                    }
3719                }
3720            }
3721            if (lrui <= mLruProcessActivityStart) {
3722                mLruProcessActivityStart--;
3723            }
3724            if (lrui <= mLruProcessServiceStart) {
3725                mLruProcessServiceStart--;
3726            }
3727            mLruProcesses.remove(lrui);
3728        }
3729    }
3730
3731    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3732            ProcessRecord client) {
3733        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3734                || app.treatLikeActivity || app.recentTasks.size() > 0;
3735        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3736        if (!activityChange && hasActivity) {
3737            // The process has activities, so we are only allowing activity-based adjustments
3738            // to move it.  It should be kept in the front of the list with other
3739            // processes that have activities, and we don't want those to change their
3740            // order except due to activity operations.
3741            return;
3742        }
3743
3744        mLruSeq++;
3745        final long now = SystemClock.uptimeMillis();
3746        app.lastActivityTime = now;
3747
3748        // First a quick reject: if the app is already at the position we will
3749        // put it, then there is nothing to do.
3750        if (hasActivity) {
3751            final int N = mLruProcesses.size();
3752            if (N > 0 && mLruProcesses.get(N-1) == app) {
3753                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3754                return;
3755            }
3756        } else {
3757            if (mLruProcessServiceStart > 0
3758                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3759                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3760                return;
3761            }
3762        }
3763
3764        int lrui = mLruProcesses.lastIndexOf(app);
3765
3766        if (app.persistent && lrui >= 0) {
3767            // We don't care about the position of persistent processes, as long as
3768            // they are in the list.
3769            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3770            return;
3771        }
3772
3773        /* In progress: compute new position first, so we can avoid doing work
3774           if the process is not actually going to move.  Not yet working.
3775        int addIndex;
3776        int nextIndex;
3777        boolean inActivity = false, inService = false;
3778        if (hasActivity) {
3779            // Process has activities, put it at the very tipsy-top.
3780            addIndex = mLruProcesses.size();
3781            nextIndex = mLruProcessServiceStart;
3782            inActivity = true;
3783        } else if (hasService) {
3784            // Process has services, put it at the top of the service list.
3785            addIndex = mLruProcessActivityStart;
3786            nextIndex = mLruProcessServiceStart;
3787            inActivity = true;
3788            inService = true;
3789        } else  {
3790            // Process not otherwise of interest, it goes to the top of the non-service area.
3791            addIndex = mLruProcessServiceStart;
3792            if (client != null) {
3793                int clientIndex = mLruProcesses.lastIndexOf(client);
3794                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3795                        + app);
3796                if (clientIndex >= 0 && addIndex > clientIndex) {
3797                    addIndex = clientIndex;
3798                }
3799            }
3800            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3801        }
3802
3803        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3804                + mLruProcessActivityStart + "): " + app);
3805        */
3806
3807        if (lrui >= 0) {
3808            if (lrui < mLruProcessActivityStart) {
3809                mLruProcessActivityStart--;
3810            }
3811            if (lrui < mLruProcessServiceStart) {
3812                mLruProcessServiceStart--;
3813            }
3814            /*
3815            if (addIndex > lrui) {
3816                addIndex--;
3817            }
3818            if (nextIndex > lrui) {
3819                nextIndex--;
3820            }
3821            */
3822            mLruProcesses.remove(lrui);
3823        }
3824
3825        /*
3826        mLruProcesses.add(addIndex, app);
3827        if (inActivity) {
3828            mLruProcessActivityStart++;
3829        }
3830        if (inService) {
3831            mLruProcessActivityStart++;
3832        }
3833        */
3834
3835        int nextIndex;
3836        if (hasActivity) {
3837            final int N = mLruProcesses.size();
3838            if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
3839                    && mLruProcessActivityStart < (N - 1)) {
3840                // Process doesn't have activities, but has clients with
3841                // activities...  move it up, but one below the top (the top
3842                // should always have a real activity).
3843                if (DEBUG_LRU) Slog.d(TAG_LRU,
3844                        "Adding to second-top of LRU activity list: " + app);
3845                mLruProcesses.add(N - 1, app);
3846                // To keep it from spamming the LRU list (by making a bunch of clients),
3847                // we will push down any other entries owned by the app.
3848                final int uid = app.info.uid;
3849                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3850                    ProcessRecord subProc = mLruProcesses.get(i);
3851                    if (subProc.info.uid == uid) {
3852                        // We want to push this one down the list.  If the process after
3853                        // it is for the same uid, however, don't do so, because we don't
3854                        // want them internally to be re-ordered.
3855                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3856                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3857                                    "Pushing uid " + uid + " swapping at " + i + ": "
3858                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3859                            ProcessRecord tmp = mLruProcesses.get(i);
3860                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3861                            mLruProcesses.set(i - 1, tmp);
3862                            i--;
3863                        }
3864                    } else {
3865                        // A gap, we can stop here.
3866                        break;
3867                    }
3868                }
3869            } else {
3870                // Process has activities, put it at the very tipsy-top.
3871                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3872                mLruProcesses.add(app);
3873            }
3874            nextIndex = mLruProcessServiceStart;
3875        } else if (hasService) {
3876            // Process has services, put it at the top of the service list.
3877            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3878            mLruProcesses.add(mLruProcessActivityStart, app);
3879            nextIndex = mLruProcessServiceStart;
3880            mLruProcessActivityStart++;
3881        } else  {
3882            // Process not otherwise of interest, it goes to the top of the non-service area.
3883            int index = mLruProcessServiceStart;
3884            if (client != null) {
3885                // If there is a client, don't allow the process to be moved up higher
3886                // in the list than that client.
3887                int clientIndex = mLruProcesses.lastIndexOf(client);
3888                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3889                        + " when updating " + app);
3890                if (clientIndex <= lrui) {
3891                    // Don't allow the client index restriction to push it down farther in the
3892                    // list than it already is.
3893                    clientIndex = lrui;
3894                }
3895                if (clientIndex >= 0 && index > clientIndex) {
3896                    index = clientIndex;
3897                }
3898            }
3899            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3900            mLruProcesses.add(index, app);
3901            nextIndex = index-1;
3902            mLruProcessActivityStart++;
3903            mLruProcessServiceStart++;
3904        }
3905
3906        // If the app is currently using a content provider or service,
3907        // bump those processes as well.
3908        for (int j=app.connections.size()-1; j>=0; j--) {
3909            ConnectionRecord cr = app.connections.valueAt(j);
3910            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3911                    && cr.binding.service.app != null
3912                    && cr.binding.service.app.lruSeq != mLruSeq
3913                    && !cr.binding.service.app.persistent) {
3914                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3915                        "service connection", cr, app);
3916            }
3917        }
3918        for (int j=app.conProviders.size()-1; j>=0; j--) {
3919            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3920            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3921                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3922                        "provider reference", cpr, app);
3923            }
3924        }
3925    }
3926
3927    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3928        if (uid == SYSTEM_UID) {
3929            // The system gets to run in any process.  If there are multiple
3930            // processes with the same uid, just pick the first (this
3931            // should never happen).
3932            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3933            if (procs == null) return null;
3934            final int procCount = procs.size();
3935            for (int i = 0; i < procCount; i++) {
3936                final int procUid = procs.keyAt(i);
3937                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3938                    // Don't use an app process or different user process for system component.
3939                    continue;
3940                }
3941                return procs.valueAt(i);
3942            }
3943        }
3944        ProcessRecord proc = mProcessNames.get(processName, uid);
3945        if (false && proc != null && !keepIfLarge
3946                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3947                && proc.lastCachedPss >= 4000) {
3948            // Turn this condition on to cause killing to happen regularly, for testing.
3949            if (proc.baseProcessTracker != null) {
3950                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3951            }
3952            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3953        } else if (proc != null && !keepIfLarge
3954                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3955                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3956            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3957            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3958                if (proc.baseProcessTracker != null) {
3959                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3960                }
3961                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3962            }
3963        }
3964        return proc;
3965    }
3966
3967    void notifyPackageUse(String packageName, int reason) {
3968        synchronized(this) {
3969            getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3970        }
3971    }
3972
3973    boolean isNextTransitionForward() {
3974        int transit = mWindowManager.getPendingAppTransition();
3975        return transit == TRANSIT_ACTIVITY_OPEN
3976                || transit == TRANSIT_TASK_OPEN
3977                || transit == TRANSIT_TASK_TO_FRONT;
3978    }
3979
3980    boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3981            String processName, String abiOverride, int uid, Runnable crashHandler) {
3982        synchronized(this) {
3983            ApplicationInfo info = new ApplicationInfo();
3984            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3985            // For isolated processes, the former contains the parent's uid and the latter the
3986            // actual uid of the isolated process.
3987            // In the special case introduced by this method (which is, starting an isolated
3988            // process directly from the SystemServer without an actual parent app process) the
3989            // closest thing to a parent's uid is SYSTEM_UID.
3990            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3991            // the |isolated| logic in the ProcessRecord constructor.
3992            info.uid = SYSTEM_UID;
3993            info.processName = processName;
3994            info.className = entryPoint;
3995            info.packageName = "android";
3996            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3997            info.targetSdkVersion = Build.VERSION.SDK_INT;
3998            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3999                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
4000                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
4001                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
4002                    crashHandler);
4003            return proc != null;
4004        }
4005    }
4006
4007    @GuardedBy("this")
4008    final ProcessRecord startProcessLocked(String processName,
4009            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
4010            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
4011            boolean isolated, boolean keepIfLarge) {
4012        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
4013                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
4014                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
4015                null /* crashHandler */);
4016    }
4017
4018    @GuardedBy("this")
4019    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
4020            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
4021            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
4022            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
4023        long startTime = SystemClock.elapsedRealtime();
4024        ProcessRecord app;
4025        if (!isolated) {
4026            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
4027            checkTime(startTime, "startProcess: after getProcessRecord");
4028
4029            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
4030                // If we are in the background, then check to see if this process
4031                // is bad.  If so, we will just silently fail.
4032                if (mAppErrors.isBadProcessLocked(info)) {
4033                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
4034                            + "/" + info.processName);
4035                    return null;
4036                }
4037            } else {
4038                // When the user is explicitly starting a process, then clear its
4039                // crash count so that we won't make it bad until they see at
4040                // least one crash dialog again, and make the process good again
4041                // if it had been bad.
4042                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
4043                        + "/" + info.processName);
4044                mAppErrors.resetProcessCrashTimeLocked(info);
4045                if (mAppErrors.isBadProcessLocked(info)) {
4046                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
4047                            UserHandle.getUserId(info.uid), info.uid,
4048                            info.processName);
4049                    mAppErrors.clearBadProcessLocked(info);
4050                    if (app != null) {
4051                        app.bad = false;
4052                    }
4053                }
4054            }
4055        } else {
4056            // If this is an isolated process, it can't re-use an existing process.
4057            app = null;
4058        }
4059
4060        // We don't have to do anything more if:
4061        // (1) There is an existing application record; and
4062        // (2) The caller doesn't think it is dead, OR there is no thread
4063        //     object attached to it so we know it couldn't have crashed; and
4064        // (3) There is a pid assigned to it, so it is either starting or
4065        //     already running.
4066        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
4067                + " app=" + app + " knownToBeDead=" + knownToBeDead
4068                + " thread=" + (app != null ? app.thread : null)
4069                + " pid=" + (app != null ? app.pid : -1));
4070        if (app != null && app.pid > 0) {
4071            if ((!knownToBeDead && !app.killed) || app.thread == null) {
4072                // We already have the app running, or are waiting for it to
4073                // come up (we have a pid but not yet its thread), so keep it.
4074                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
4075                // If this is a new package in the process, add the package to the list
4076                app.addPackage(info.packageName, info.versionCode, mProcessStats);
4077                checkTime(startTime, "startProcess: done, added package to proc");
4078                return app;
4079            }
4080
4081            // An application record is attached to a previous process,
4082            // clean it up now.
4083            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
4084            checkTime(startTime, "startProcess: bad proc running, killing");
4085            killProcessGroup(app.uid, app.pid);
4086            handleAppDiedLocked(app, true, true);
4087            checkTime(startTime, "startProcess: done killing old proc");
4088        }
4089
4090        String hostingNameStr = hostingName != null
4091                ? hostingName.flattenToShortString() : null;
4092
4093        if (app == null) {
4094            checkTime(startTime, "startProcess: creating new process record");
4095            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
4096            if (app == null) {
4097                Slog.w(TAG, "Failed making new process record for "
4098                        + processName + "/" + info.uid + " isolated=" + isolated);
4099                return null;
4100            }
4101            app.crashHandler = crashHandler;
4102            app.isolatedEntryPoint = entryPoint;
4103            app.isolatedEntryPointArgs = entryPointArgs;
4104            checkTime(startTime, "startProcess: done creating new process record");
4105        } else {
4106            // If this is a new package in the process, add the package to the list
4107            app.addPackage(info.packageName, info.versionCode, mProcessStats);
4108            checkTime(startTime, "startProcess: added package to existing proc");
4109        }
4110
4111        // If the system is not ready yet, then hold off on starting this
4112        // process until it is.
4113        if (!mProcessesReady
4114                && !isAllowedWhileBooting(info)
4115                && !allowWhileBooting) {
4116            if (!mProcessesOnHold.contains(app)) {
4117                mProcessesOnHold.add(app);
4118            }
4119            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
4120                    "System not ready, putting on hold: " + app);
4121            checkTime(startTime, "startProcess: returning with proc on hold");
4122            return app;
4123        }
4124
4125        checkTime(startTime, "startProcess: stepping in to startProcess");
4126        final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
4127        checkTime(startTime, "startProcess: done starting proc!");
4128        return success ? app : null;
4129    }
4130
4131    boolean isAllowedWhileBooting(ApplicationInfo ai) {
4132        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
4133    }
4134
4135    @GuardedBy("this")
4136    private final void startProcessLocked(ProcessRecord app,
4137            String hostingType, String hostingNameStr) {
4138        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
4139    }
4140
4141    @GuardedBy("this")
4142    private final boolean startProcessLocked(ProcessRecord app,
4143            String hostingType, String hostingNameStr, String abiOverride) {
4144        return startProcessLocked(app, hostingType, hostingNameStr,
4145                false /* disableHiddenApiChecks */, abiOverride);
4146    }
4147
4148    /**
4149     * @return {@code true} if process start is successful, false otherwise.
4150     */
4151    @GuardedBy("this")
4152    private final boolean startProcessLocked(ProcessRecord app, String hostingType,
4153            String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
4154        if (app.pendingStart) {
4155            return true;
4156        }
4157        long startTime = SystemClock.elapsedRealtime();
4158        if (app.pid > 0 && app.pid != MY_PID) {
4159            checkTime(startTime, "startProcess: removing from pids map");
4160            synchronized (mPidsSelfLocked) {
4161                mPidsSelfLocked.remove(app.pid);
4162                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4163            }
4164            checkTime(startTime, "startProcess: done removing from pids map");
4165            app.setPid(0);
4166        }
4167
4168        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
4169                "startProcessLocked removing on hold: " + app);
4170        mProcessesOnHold.remove(app);
4171
4172        checkTime(startTime, "startProcess: starting to update cpu stats");
4173        updateCpuStats();
4174        checkTime(startTime, "startProcess: done updating cpu stats");
4175
4176        try {
4177            try {
4178                final int userId = UserHandle.getUserId(app.uid);
4179                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
4180            } catch (RemoteException e) {
4181                throw e.rethrowAsRuntimeException();
4182            }
4183
4184            int uid = app.uid;
4185            int[] gids = null;
4186            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
4187            if (!app.isolated) {
4188                int[] permGids = null;
4189                try {
4190                    checkTime(startTime, "startProcess: getting gids from package manager");
4191                    final IPackageManager pm = AppGlobals.getPackageManager();
4192                    permGids = pm.getPackageGids(app.info.packageName,
4193                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
4194                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
4195                            StorageManagerInternal.class);
4196                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
4197                            app.info.packageName);
4198                } catch (RemoteException e) {
4199                    throw e.rethrowAsRuntimeException();
4200                }
4201
4202                /*
4203                 * Add shared application and profile GIDs so applications can share some
4204                 * resources like shared libraries and access user-wide resources
4205                 */
4206                if (ArrayUtils.isEmpty(permGids)) {
4207                    gids = new int[3];
4208                } else {
4209                    gids = new int[permGids.length + 3];
4210                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
4211                }
4212                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
4213                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
4214                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
4215
4216                // Replace any invalid GIDs
4217                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
4218                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
4219            }
4220            checkTime(startTime, "startProcess: building args");
4221            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
4222                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4223                        && mTopComponent != null
4224                        && app.processName.equals(mTopComponent.getPackageName())) {
4225                    uid = 0;
4226                }
4227                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
4228                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
4229                    uid = 0;
4230                }
4231            }
4232            int runtimeFlags = 0;
4233            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4234                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
4235                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
4236                // Also turn on CheckJNI for debuggable apps. It's quite
4237                // awkward to turn on otherwise.
4238                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4239            }
4240            // Run the app in safe mode if its manifest requests so or the
4241            // system is booted in safe mode.
4242            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
4243                mSafeMode == true) {
4244                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
4245            }
4246            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
4247                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4248            }
4249            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
4250            if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
4251                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
4252            }
4253            String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
4254            if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
4255                runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
4256            }
4257            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
4258                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
4259            }
4260            if ("1".equals(SystemProperties.get("debug.assert"))) {
4261                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
4262            }
4263            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
4264                // Enable all debug flags required by the native debugger.
4265                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
4266                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
4267                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
4268                mNativeDebuggingApp = null;
4269            }
4270
4271            if (app.info.isPrivilegedApp() &&
4272                    SystemProperties.getBoolean("pm.dexopt.priv-apps-oob", false)) {
4273                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
4274            }
4275
4276            if (!disableHiddenApiChecks && !mHiddenApiBlacklist.isDisabled()) {
4277                app.info.maybeUpdateHiddenApiEnforcementPolicy(
4278                        mHiddenApiBlacklist.getPolicyForPrePApps(),
4279                        mHiddenApiBlacklist.getPolicyForPApps());
4280                @HiddenApiEnforcementPolicy int policy =
4281                        app.info.getHiddenApiEnforcementPolicy();
4282                int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
4283                if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
4284                    throw new IllegalStateException("Invalid API policy: " + policy);
4285                }
4286                runtimeFlags |= policyBits;
4287            }
4288
4289            String invokeWith = null;
4290            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4291                // Debuggable apps may include a wrapper script with their library directory.
4292                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
4293                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4294                try {
4295                    if (new File(wrapperFileName).exists()) {
4296                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
4297                    }
4298                } finally {
4299                    StrictMode.setThreadPolicy(oldPolicy);
4300                }
4301            }
4302
4303            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
4304            if (requiredAbi == null) {
4305                requiredAbi = Build.SUPPORTED_ABIS[0];
4306            }
4307
4308            String instructionSet = null;
4309            if (app.info.primaryCpuAbi != null) {
4310                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
4311            }
4312
4313            app.gids = gids;
4314            app.requiredAbi = requiredAbi;
4315            app.instructionSet = instructionSet;
4316
4317            // the per-user SELinux context must be set
4318            if (TextUtils.isEmpty(app.info.seInfoUser)) {
4319                Slog.wtf(TAG, "SELinux tag not defined",
4320                        new IllegalStateException("SELinux tag not defined for "
4321                        + app.info.packageName + " (uid " + app.uid + ")"));
4322            }
4323            final String seInfo = app.info.seInfo
4324                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
4325            // Start the process.  It will either succeed and return a result containing
4326            // the PID of the new process, or else throw a RuntimeException.
4327            final String entryPoint = "android.app.ActivityThread";
4328
4329            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
4330                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
4331                    startTime);
4332        } catch (RuntimeException e) {
4333            Slog.e(TAG, "Failure starting process " + app.processName, e);
4334
4335            // Something went very wrong while trying to start this process; one
4336            // common case is when the package is frozen due to an active
4337            // upgrade. To recover, clean up any active bookkeeping related to
4338            // starting this process. (We already invoked this method once when
4339            // the package was initially frozen through KILL_APPLICATION_MSG, so
4340            // it doesn't hurt to use it again.)
4341            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4342                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4343            return false;
4344        }
4345    }
4346
4347    @GuardedBy("this")
4348    private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
4349            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4350            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4351            long startTime) {
4352        app.pendingStart = true;
4353        app.killedByAm = false;
4354        app.removed = false;
4355        app.killed = false;
4356        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
4357        app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
4358        if (mConstants.FLAG_PROCESS_START_ASYNC) {
4359            if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
4360                    "Posting procStart msg for " + app.toShortString());
4361            mProcStartHandler.post(() -> {
4362                try {
4363                    synchronized (ActivityManagerService.this) {
4364                        final String reason = isProcStartValidLocked(app, startSeq);
4365                        if (reason != null) {
4366                            Slog.w(TAG_PROCESSES, app + " not valid anymore,"
4367                                    + " don't start process, " + reason);
4368                            app.pendingStart = false;
4369                            return;
4370                        }
4371                        app.usingWrapper = invokeWith != null
4372                                || SystemProperties.get("wrap." + app.processName) != null;
4373                        mPendingStarts.put(startSeq, app);
4374                    }
4375                    final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
4376                            app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
4377                            requiredAbi, instructionSet, invokeWith, app.startTime);
4378                    synchronized (ActivityManagerService.this) {
4379                        handleProcessStartedLocked(app, startResult, startSeq);
4380                    }
4381                } catch (RuntimeException e) {
4382                    synchronized (ActivityManagerService.this) {
4383                        Slog.e(TAG, "Failure starting process " + app.processName, e);
4384                        mPendingStarts.remove(startSeq);
4385                        app.pendingStart = false;
4386                        forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4387                                false, false, true, false, false,
4388                                UserHandle.getUserId(app.userId), "start failure");
4389                    }
4390                }
4391            });
4392            return true;
4393        } else {
4394            try {
4395                final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
4396                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
4397                        invokeWith, startTime);
4398                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
4399                        startSeq, false);
4400            } catch (RuntimeException e) {
4401                Slog.e(TAG, "Failure starting process " + app.processName, e);
4402                app.pendingStart = false;
4403                forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4404                        false, false, true, false, false,
4405                        UserHandle.getUserId(app.userId), "start failure");
4406            }
4407            return app.pid > 0;
4408        }
4409    }
4410
4411    private ProcessStartResult startProcess(String hostingType, String entryPoint,
4412            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4413            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4414            long startTime) {
4415        try {
4416            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
4417                    app.processName);
4418            checkTime(startTime, "startProcess: asking zygote to start proc");
4419            final ProcessStartResult startResult;
4420            if (hostingType.equals("webview_service")) {
4421                startResult = startWebView(entryPoint,
4422                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4423                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4424                        app.info.dataDir, null,
4425                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4426            } else {
4427                startResult = Process.start(entryPoint,
4428                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4429                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4430                        app.info.dataDir, invokeWith,
4431                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4432            }
4433            checkTime(startTime, "startProcess: returned from zygote!");
4434            return startResult;
4435        } finally {
4436            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4437        }
4438    }
4439
4440    @GuardedBy("this")
4441    private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
4442        StringBuilder sb = null;
4443        if (app.killedByAm) {
4444            if (sb == null) sb = new StringBuilder();
4445            sb.append("killedByAm=true;");
4446        }
4447        if (mProcessNames.get(app.processName, app.uid) != app) {
4448            if (sb == null) sb = new StringBuilder();
4449            sb.append("No entry in mProcessNames;");
4450        }
4451        if (!app.pendingStart) {
4452            if (sb == null) sb = new StringBuilder();
4453            sb.append("pendingStart=false;");
4454        }
4455        if (app.startSeq > expectedStartSeq) {
4456            if (sb == null) sb = new StringBuilder();
4457            sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
4458        }
4459        return sb == null ? null : sb.toString();
4460    }
4461
4462    @GuardedBy("this")
4463    private boolean handleProcessStartedLocked(ProcessRecord pending,
4464            ProcessStartResult startResult, long expectedStartSeq) {
4465        // Indicates that this process start has been taken care of.
4466        if (mPendingStarts.get(expectedStartSeq) == null) {
4467            if (pending.pid == startResult.pid) {
4468                pending.usingWrapper = startResult.usingWrapper;
4469                // TODO: Update already existing clients of usingWrapper
4470            }
4471            return false;
4472        }
4473        return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
4474                expectedStartSeq, false);
4475    }
4476
4477    @GuardedBy("this")
4478    private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
4479            long expectedStartSeq, boolean procAttached) {
4480        mPendingStarts.remove(expectedStartSeq);
4481        final String reason = isProcStartValidLocked(app, expectedStartSeq);
4482        if (reason != null) {
4483            Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
4484                    + ", " + reason);
4485            app.pendingStart = false;
4486            Process.killProcessQuiet(pid);
4487            Process.killProcessGroup(app.uid, app.pid);
4488            return false;
4489        }
4490        mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
4491        checkTime(app.startTime, "startProcess: done updating battery stats");
4492
4493        EventLog.writeEvent(EventLogTags.AM_PROC_START,
4494                UserHandle.getUserId(app.startUid), pid, app.startUid,
4495                app.processName, app.hostingType,
4496                app.hostingNameStr != null ? app.hostingNameStr : "");
4497
4498        try {
4499            AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
4500                    app.seInfo, app.info.sourceDir, pid);
4501        } catch (RemoteException ex) {
4502            // Ignore
4503        }
4504
4505        if (app.persistent) {
4506            Watchdog.getInstance().processStarted(app.processName, pid);
4507        }
4508
4509        checkTime(app.startTime, "startProcess: building log message");
4510        StringBuilder buf = mStringBuilder;
4511        buf.setLength(0);
4512        buf.append("Start proc ");
4513        buf.append(pid);
4514        buf.append(':');
4515        buf.append(app.processName);
4516        buf.append('/');
4517        UserHandle.formatUid(buf, app.startUid);
4518        if (app.isolatedEntryPoint != null) {
4519            buf.append(" [");
4520            buf.append(app.isolatedEntryPoint);
4521            buf.append("]");
4522        }
4523        buf.append(" for ");
4524        buf.append(app.hostingType);
4525        if (app.hostingNameStr != null) {
4526            buf.append(" ");
4527            buf.append(app.hostingNameStr);
4528        }
4529        reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
4530        app.setPid(pid);
4531        app.usingWrapper = usingWrapper;
4532        app.pendingStart = false;
4533        checkTime(app.startTime, "startProcess: starting to update pids map");
4534        ProcessRecord oldApp;
4535        synchronized (mPidsSelfLocked) {
4536            oldApp = mPidsSelfLocked.get(pid);
4537        }
4538        // If there is already an app occupying that pid that hasn't been cleaned up
4539        if (oldApp != null && !app.isolated) {
4540            // Clean up anything relating to this pid first
4541            Slog.w(TAG, "Reusing pid " + pid
4542                    + " while app is still mapped to it");
4543            cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4544                    true /*replacingPid*/);
4545        }
4546        synchronized (mPidsSelfLocked) {
4547            this.mPidsSelfLocked.put(pid, app);
4548            if (!procAttached) {
4549                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4550                msg.obj = app;
4551                mHandler.sendMessageDelayed(msg, usingWrapper
4552                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4553            }
4554        }
4555        checkTime(app.startTime, "startProcess: done updating pids map");
4556        return true;
4557    }
4558
4559    void updateUsageStats(ActivityRecord component, boolean resumed) {
4560        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4561                "updateUsageStats: comp=" + component + "res=" + resumed);
4562        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4563        StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
4564            component.app.uid, component.realActivity.getPackageName(),
4565            component.realActivity.getShortClassName(), resumed ?
4566                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND :
4567                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND);
4568        if (resumed) {
4569            if (mUsageStatsService != null) {
4570                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4571                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4572
4573            }
4574            synchronized (stats) {
4575                stats.noteActivityResumedLocked(component.app.uid);
4576            }
4577        } else {
4578            if (mUsageStatsService != null) {
4579                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4580                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4581            }
4582            synchronized (stats) {
4583                stats.noteActivityPausedLocked(component.app.uid);
4584            }
4585        }
4586    }
4587
4588    Intent getHomeIntent() {
4589        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4590        intent.setComponent(mTopComponent);
4591        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4592        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4593            intent.addCategory(Intent.CATEGORY_HOME);
4594        }
4595        return intent;
4596    }
4597
4598    boolean startHomeActivityLocked(int userId, String reason) {
4599        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4600                && mTopAction == null) {
4601            // We are running in factory test mode, but unable to find
4602            // the factory test app, so just sit around displaying the
4603            // error message and don't try to start anything.
4604            return false;
4605        }
4606        Intent intent = getHomeIntent();
4607        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4608        if (aInfo != null) {
4609            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4610            // Don't do this if the home app is currently being
4611            // instrumented.
4612            aInfo = new ActivityInfo(aInfo);
4613            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4614            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4615                    aInfo.applicationInfo.uid, true);
4616            if (app == null || app.instr == null) {
4617                intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
4618                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4619                // For ANR debugging to verify if the user activity is the one that actually
4620                // launched.
4621                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4622                mActivityStartController.startHomeActivity(intent, aInfo, myReason);
4623            }
4624        } else {
4625            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4626        }
4627
4628        return true;
4629    }
4630
4631    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4632        ActivityInfo ai = null;
4633        ComponentName comp = intent.getComponent();
4634        try {
4635            if (comp != null) {
4636                // Factory test.
4637                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4638            } else {
4639                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4640                        intent,
4641                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4642                        flags, userId);
4643
4644                if (info != null) {
4645                    ai = info.activityInfo;
4646                }
4647            }
4648        } catch (RemoteException e) {
4649            // ignore
4650        }
4651
4652        return ai;
4653    }
4654
4655    boolean getCheckedForSetup() {
4656        return mCheckedForSetup;
4657    }
4658
4659    void setCheckedForSetup(boolean checked) {
4660        mCheckedForSetup = checked;
4661    }
4662
4663    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4664        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4665    }
4666
4667    void enforceNotIsolatedCaller(String caller) {
4668        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4669            throw new SecurityException("Isolated process not allowed to call " + caller);
4670        }
4671    }
4672
4673    @Override
4674    public int getFrontActivityScreenCompatMode() {
4675        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4676        synchronized (this) {
4677            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4678        }
4679    }
4680
4681    @Override
4682    public void setFrontActivityScreenCompatMode(int mode) {
4683        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4684                "setFrontActivityScreenCompatMode");
4685        synchronized (this) {
4686            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4687        }
4688    }
4689
4690    @Override
4691    public int getPackageScreenCompatMode(String packageName) {
4692        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4693        synchronized (this) {
4694            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4695        }
4696    }
4697
4698    @Override
4699    public void setPackageScreenCompatMode(String packageName, int mode) {
4700        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4701                "setPackageScreenCompatMode");
4702        synchronized (this) {
4703            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4704        }
4705    }
4706
4707    @Override
4708    public boolean getPackageAskScreenCompat(String packageName) {
4709        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4710        synchronized (this) {
4711            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4712        }
4713    }
4714
4715    @Override
4716    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4717        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4718                "setPackageAskScreenCompat");
4719        synchronized (this) {
4720            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4721        }
4722    }
4723
4724    private boolean hasUsageStatsPermission(String callingPackage) {
4725        final int mode = mAppOpsService.noteOperation(AppOpsManager.OP_GET_USAGE_STATS,
4726                Binder.getCallingUid(), callingPackage);
4727        if (mode == AppOpsManager.MODE_DEFAULT) {
4728            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4729                    == PackageManager.PERMISSION_GRANTED;
4730        }
4731        return mode == AppOpsManager.MODE_ALLOWED;
4732    }
4733
4734    @Override
4735    public int getPackageProcessState(String packageName, String callingPackage) {
4736        if (!hasUsageStatsPermission(callingPackage)) {
4737            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4738                    "getPackageProcessState");
4739        }
4740
4741        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4742        synchronized (this) {
4743            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4744                final ProcessRecord proc = mLruProcesses.get(i);
4745                if (procState > proc.setProcState) {
4746                    if (proc.pkgList.containsKey(packageName) ||
4747                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4748                        procState = proc.setProcState;
4749                    }
4750                }
4751            }
4752        }
4753        return procState;
4754    }
4755
4756    @Override
4757    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4758            throws RemoteException {
4759        synchronized (this) {
4760            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4761            if (app == null) {
4762                throw new IllegalArgumentException("Unknown process: " + process);
4763            }
4764            if (app.thread == null) {
4765                throw new IllegalArgumentException("Process has no app thread");
4766            }
4767            if (app.trimMemoryLevel >= level) {
4768                throw new IllegalArgumentException(
4769                        "Unable to set a higher trim level than current level");
4770            }
4771            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4772                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4773                throw new IllegalArgumentException("Unable to set a background trim level "
4774                    + "on a foreground process");
4775            }
4776            app.thread.scheduleTrimMemory(level);
4777            app.trimMemoryLevel = level;
4778            return true;
4779        }
4780    }
4781
4782    private void dispatchProcessesChanged() {
4783        int N;
4784        synchronized (this) {
4785            N = mPendingProcessChanges.size();
4786            if (mActiveProcessChanges.length < N) {
4787                mActiveProcessChanges = new ProcessChangeItem[N];
4788            }
4789            mPendingProcessChanges.toArray(mActiveProcessChanges);
4790            mPendingProcessChanges.clear();
4791            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4792                    "*** Delivering " + N + " process changes");
4793        }
4794
4795        int i = mProcessObservers.beginBroadcast();
4796        while (i > 0) {
4797            i--;
4798            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4799            if (observer != null) {
4800                try {
4801                    for (int j=0; j<N; j++) {
4802                        ProcessChangeItem item = mActiveProcessChanges[j];
4803                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4804                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4805                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4806                                    + item.uid + ": " + item.foregroundActivities);
4807                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4808                                    item.foregroundActivities);
4809                        }
4810                    }
4811                } catch (RemoteException e) {
4812                }
4813            }
4814        }
4815        mProcessObservers.finishBroadcast();
4816
4817        synchronized (this) {
4818            for (int j=0; j<N; j++) {
4819                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4820            }
4821        }
4822    }
4823
4824    private void dispatchProcessDied(int pid, int uid) {
4825        int i = mProcessObservers.beginBroadcast();
4826        while (i > 0) {
4827            i--;
4828            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4829            if (observer != null) {
4830                try {
4831                    observer.onProcessDied(pid, uid);
4832                } catch (RemoteException e) {
4833                }
4834            }
4835        }
4836        mProcessObservers.finishBroadcast();
4837    }
4838
4839    @VisibleForTesting
4840    void dispatchUidsChanged() {
4841        int N;
4842        synchronized (this) {
4843            N = mPendingUidChanges.size();
4844            if (mActiveUidChanges.length < N) {
4845                mActiveUidChanges = new UidRecord.ChangeItem[N];
4846            }
4847            for (int i=0; i<N; i++) {
4848                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4849                mActiveUidChanges[i] = change;
4850                if (change.uidRecord != null) {
4851                    change.uidRecord.pendingChange = null;
4852                    change.uidRecord = null;
4853                }
4854            }
4855            mPendingUidChanges.clear();
4856            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4857                    "*** Delivering " + N + " uid changes");
4858        }
4859
4860        mUidChangeDispatchCount += N;
4861        int i = mUidObservers.beginBroadcast();
4862        while (i > 0) {
4863            i--;
4864            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4865                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4866        }
4867        mUidObservers.finishBroadcast();
4868
4869        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4870            for (int j = 0; j < N; ++j) {
4871                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4872                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4873                    mValidateUids.remove(item.uid);
4874                } else {
4875                    UidRecord validateUid = mValidateUids.get(item.uid);
4876                    if (validateUid == null) {
4877                        validateUid = new UidRecord(item.uid);
4878                        mValidateUids.put(item.uid, validateUid);
4879                    }
4880                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4881                        validateUid.idle = true;
4882                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4883                        validateUid.idle = false;
4884                    }
4885                    validateUid.curProcState = validateUid.setProcState = item.processState;
4886                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4887                }
4888            }
4889        }
4890
4891        synchronized (this) {
4892            for (int j = 0; j < N; j++) {
4893                mAvailUidChanges.add(mActiveUidChanges[j]);
4894            }
4895        }
4896    }
4897
4898    private void dispatchUidsChangedForObserver(IUidObserver observer,
4899            UidObserverRegistration reg, int changesSize) {
4900        if (observer == null) {
4901            return;
4902        }
4903        try {
4904            for (int j = 0; j < changesSize; j++) {
4905                UidRecord.ChangeItem item = mActiveUidChanges[j];
4906                final int change = item.change;
4907                if (change == UidRecord.CHANGE_PROCSTATE &&
4908                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4909                    // No-op common case: no significant change, the observer is not
4910                    // interested in all proc state changes.
4911                    continue;
4912                }
4913                final long start = SystemClock.uptimeMillis();
4914                if ((change & UidRecord.CHANGE_IDLE) != 0) {
4915                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4916                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4917                                "UID idle uid=" + item.uid);
4918                        observer.onUidIdle(item.uid, item.ephemeral);
4919                    }
4920                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4921                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4922                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4923                                "UID active uid=" + item.uid);
4924                        observer.onUidActive(item.uid);
4925                    }
4926                }
4927                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4928                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
4929                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4930                                "UID cached uid=" + item.uid);
4931                        observer.onUidCachedChanged(item.uid, true);
4932                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4933                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4934                                "UID active uid=" + item.uid);
4935                        observer.onUidCachedChanged(item.uid, false);
4936                    }
4937                }
4938                if ((change & UidRecord.CHANGE_GONE) != 0) {
4939                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4940                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4941                                "UID gone uid=" + item.uid);
4942                        observer.onUidGone(item.uid, item.ephemeral);
4943                    }
4944                    if (reg.lastProcStates != null) {
4945                        reg.lastProcStates.delete(item.uid);
4946                    }
4947                } else {
4948                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4949                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4950                                "UID CHANGED uid=" + item.uid
4951                                        + ": " + item.processState);
4952                        boolean doReport = true;
4953                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4954                            final int lastState = reg.lastProcStates.get(item.uid,
4955                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4956                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4957                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4958                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4959                                doReport = lastAboveCut != newAboveCut;
4960                            } else {
4961                                doReport = item.processState
4962                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4963                            }
4964                        }
4965                        if (doReport) {
4966                            if (reg.lastProcStates != null) {
4967                                reg.lastProcStates.put(item.uid, item.processState);
4968                            }
4969                            observer.onUidStateChanged(item.uid, item.processState,
4970                                    item.procStateSeq);
4971                        }
4972                    }
4973                }
4974                final int duration = (int) (SystemClock.uptimeMillis() - start);
4975                if (reg.mMaxDispatchTime < duration) {
4976                    reg.mMaxDispatchTime = duration;
4977                }
4978                if (duration >= SLOW_UID_OBSERVER_THRESHOLD_MS) {
4979                    reg.mSlowDispatchCount++;
4980                }
4981            }
4982        } catch (RemoteException e) {
4983        }
4984    }
4985
4986    void dispatchOomAdjObserver(String msg) {
4987        OomAdjObserver observer;
4988        synchronized (this) {
4989            observer = mCurOomAdjObserver;
4990        }
4991
4992        if (observer != null) {
4993            observer.onOomAdjMessage(msg);
4994        }
4995    }
4996
4997    void setOomAdjObserver(int uid, OomAdjObserver observer) {
4998        synchronized (this) {
4999            mCurOomAdjUid = uid;
5000            mCurOomAdjObserver = observer;
5001        }
5002    }
5003
5004    void clearOomAdjObserver() {
5005        synchronized (this) {
5006            mCurOomAdjUid = -1;
5007            mCurOomAdjObserver = null;
5008        }
5009    }
5010
5011    void reportOomAdjMessageLocked(String tag, String msg) {
5012        Slog.d(tag, msg);
5013        if (mCurOomAdjObserver != null) {
5014            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
5015        }
5016    }
5017
5018    void reportUidInfoMessageLocked(String tag, String msg, int uid) {
5019        Slog.i(TAG, msg);
5020        if (mCurOomAdjObserver != null && uid == mCurOomAdjUid) {
5021            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
5022        }
5023
5024    }
5025
5026    @Override
5027    public final int startActivity(IApplicationThread caller, String callingPackage,
5028            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5029            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
5030        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
5031                resultWho, requestCode, startFlags, profilerInfo, bOptions,
5032                UserHandle.getCallingUserId());
5033    }
5034
5035    @Override
5036    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
5037            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5038            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
5039        enforceNotIsolatedCaller("startActivity");
5040        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5041                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
5042        // TODO: Switch to user app stacks here.
5043        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
5044                .setCaller(caller)
5045                .setCallingPackage(callingPackage)
5046                .setResolvedType(resolvedType)
5047                .setResultTo(resultTo)
5048                .setResultWho(resultWho)
5049                .setRequestCode(requestCode)
5050                .setStartFlags(startFlags)
5051                .setProfilerInfo(profilerInfo)
5052                .setActivityOptions(bOptions)
5053                .setMayWait(userId)
5054                .execute();
5055
5056    }
5057
5058    @Override
5059    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
5060            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5061            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
5062            int userId) {
5063
5064        // This is very dangerous -- it allows you to perform a start activity (including
5065        // permission grants) as any app that may launch one of your own activities.  So
5066        // we will only allow this to be done from activities that are part of the core framework,
5067        // and then only when they are running as the system.
5068        final ActivityRecord sourceRecord;
5069        final int targetUid;
5070        final String targetPackage;
5071        synchronized (this) {
5072            if (resultTo == null) {
5073                throw new SecurityException("Must be called from an activity");
5074            }
5075            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
5076            if (sourceRecord == null) {
5077                throw new SecurityException("Called with bad activity token: " + resultTo);
5078            }
5079            if (!sourceRecord.info.packageName.equals("android")) {
5080                throw new SecurityException(
5081                        "Must be called from an activity that is declared in the android package");
5082            }
5083            if (sourceRecord.app == null) {
5084                throw new SecurityException("Called without a process attached to activity");
5085            }
5086            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
5087                // This is still okay, as long as this activity is running under the
5088                // uid of the original calling activity.
5089                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
5090                    throw new SecurityException(
5091                            "Calling activity in uid " + sourceRecord.app.uid
5092                                    + " must be system uid or original calling uid "
5093                                    + sourceRecord.launchedFromUid);
5094                }
5095            }
5096            if (ignoreTargetSecurity) {
5097                if (intent.getComponent() == null) {
5098                    throw new SecurityException(
5099                            "Component must be specified with ignoreTargetSecurity");
5100                }
5101                if (intent.getSelector() != null) {
5102                    throw new SecurityException(
5103                            "Selector not allowed with ignoreTargetSecurity");
5104                }
5105            }
5106            targetUid = sourceRecord.launchedFromUid;
5107            targetPackage = sourceRecord.launchedFromPackage;
5108        }
5109
5110        if (userId == UserHandle.USER_NULL) {
5111            userId = UserHandle.getUserId(sourceRecord.app.uid);
5112        }
5113
5114        // TODO: Switch to user app stacks here.
5115        try {
5116            return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
5117                    .setCallingUid(targetUid)
5118                    .setCallingPackage(targetPackage)
5119                    .setResolvedType(resolvedType)
5120                    .setResultTo(resultTo)
5121                    .setResultWho(resultWho)
5122                    .setRequestCode(requestCode)
5123                    .setStartFlags(startFlags)
5124                    .setActivityOptions(bOptions)
5125                    .setMayWait(userId)
5126                    .setIgnoreTargetSecurity(ignoreTargetSecurity)
5127                    .execute();
5128        } catch (SecurityException e) {
5129            // XXX need to figure out how to propagate to original app.
5130            // A SecurityException here is generally actually a fault of the original
5131            // calling activity (such as a fairly granting permissions), so propagate it
5132            // back to them.
5133            /*
5134            StringBuilder msg = new StringBuilder();
5135            msg.append("While launching");
5136            msg.append(intent.toString());
5137            msg.append(": ");
5138            msg.append(e.getMessage());
5139            */
5140            throw e;
5141        }
5142    }
5143
5144    @Override
5145    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
5146            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5147            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
5148        enforceNotIsolatedCaller("startActivityAndWait");
5149        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5150                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
5151        WaitResult res = new WaitResult();
5152        // TODO: Switch to user app stacks here.
5153        mActivityStartController.obtainStarter(intent, "startActivityAndWait")
5154                .setCaller(caller)
5155                .setCallingPackage(callingPackage)
5156                .setResolvedType(resolvedType)
5157                .setResultTo(resultTo)
5158                .setResultWho(resultWho)
5159                .setRequestCode(requestCode)
5160                .setStartFlags(startFlags)
5161                .setActivityOptions(bOptions)
5162                .setMayWait(userId)
5163                .setProfilerInfo(profilerInfo)
5164                .setWaitResult(res)
5165                .execute();
5166        return res;
5167    }
5168
5169    @Override
5170    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
5171            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5172            int startFlags, Configuration config, Bundle bOptions, int userId) {
5173        enforceNotIsolatedCaller("startActivityWithConfig");
5174        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5175                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
5176        // TODO: Switch to user app stacks here.
5177        return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
5178                .setCaller(caller)
5179                .setCallingPackage(callingPackage)
5180                .setResolvedType(resolvedType)
5181                .setResultTo(resultTo)
5182                .setResultWho(resultWho)
5183                .setRequestCode(requestCode)
5184                .setStartFlags(startFlags)
5185                .setGlobalConfiguration(config)
5186                .setActivityOptions(bOptions)
5187                .setMayWait(userId)
5188                .execute();
5189    }
5190
5191    @Override
5192    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
5193            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
5194            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
5195            throws TransactionTooLargeException {
5196        enforceNotIsolatedCaller("startActivityIntentSender");
5197        // Refuse possible leaked file descriptors
5198        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
5199            throw new IllegalArgumentException("File descriptors passed in Intent");
5200        }
5201
5202        if (!(target instanceof PendingIntentRecord)) {
5203            throw new IllegalArgumentException("Bad PendingIntent object");
5204        }
5205
5206        PendingIntentRecord pir = (PendingIntentRecord)target;
5207
5208        synchronized (this) {
5209            // If this is coming from the currently resumed activity, it is
5210            // effectively saying that app switches are allowed at this point.
5211            final ActivityStack stack = getFocusedStack();
5212            if (stack.mResumedActivity != null &&
5213                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
5214                mAppSwitchesAllowedTime = 0;
5215            }
5216        }
5217        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
5218                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
5219        return ret;
5220    }
5221
5222    @Override
5223    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
5224            Intent intent, String resolvedType, IVoiceInteractionSession session,
5225            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
5226            Bundle bOptions, int userId) {
5227        enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
5228        if (session == null || interactor == null) {
5229            throw new NullPointerException("null session or interactor");
5230        }
5231        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5232                ALLOW_FULL_ONLY, "startVoiceActivity", null);
5233        // TODO: Switch to user app stacks here.
5234        return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
5235                .setCallingUid(callingUid)
5236                .setCallingPackage(callingPackage)
5237                .setResolvedType(resolvedType)
5238                .setVoiceSession(session)
5239                .setVoiceInteractor(interactor)
5240                .setStartFlags(startFlags)
5241                .setProfilerInfo(profilerInfo)
5242                .setActivityOptions(bOptions)
5243                .setMayWait(userId)
5244                .execute();
5245    }
5246
5247    @Override
5248    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
5249            Intent intent, String resolvedType, Bundle bOptions, int userId) {
5250        enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
5251        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5252                ALLOW_FULL_ONLY, "startAssistantActivity", null);
5253
5254        return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
5255                .setCallingUid(callingUid)
5256                .setCallingPackage(callingPackage)
5257                .setResolvedType(resolvedType)
5258                .setActivityOptions(bOptions)
5259                .setMayWait(userId)
5260                .execute();
5261    }
5262
5263    @Override
5264    public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
5265                IRecentsAnimationRunner recentsAnimationRunner) {
5266        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
5267        final int callingPid = Binder.getCallingPid();
5268        final long origId = Binder.clearCallingIdentity();
5269        try {
5270            final int recentsUid;
5271            final String recentsPackage;
5272            final List<IBinder> topVisibleActivities;
5273            synchronized (this) {
5274                final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
5275                recentsPackage = recentsComponent.getPackageName();
5276                recentsUid = mRecentTasks.getRecentsComponentUid();
5277                topVisibleActivities = mStackSupervisor.getTopVisibleActivities();
5278
5279                // Start a new recents animation
5280                final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
5281                        mActivityStartController, mWindowManager, mUserController, callingPid);
5282                anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
5283                        recentsUid);
5284            }
5285
5286            // If provided, kick off the request for the assist data in the background. Do not hold
5287            // the AM lock as this will just proxy directly to the assist data receiver provided.
5288            if (assistDataReceiver != null) {
5289                final AppOpsManager appOpsManager = (AppOpsManager)
5290                        mContext.getSystemService(Context.APP_OPS_SERVICE);
5291                final AssistDataReceiverProxy proxy = new AssistDataReceiverProxy(
5292                        assistDataReceiver, recentsPackage);
5293                final AssistDataRequester requester = new AssistDataRequester(mContext, this,
5294                        mWindowManager, appOpsManager, proxy, this, OP_ASSIST_STRUCTURE, OP_NONE);
5295                requester.requestAssistData(topVisibleActivities,
5296                        true /* fetchData */, false /* fetchScreenshots */,
5297                        true /* allowFetchData */, false /* allowFetchScreenshots */,
5298                        recentsUid, recentsPackage);
5299            }
5300        } finally {
5301            Binder.restoreCallingIdentity(origId);
5302        }
5303    }
5304
5305    @Override
5306    public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5307        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
5308        final long origId = Binder.clearCallingIdentity();
5309        try {
5310            synchronized (this) {
5311                mWindowManager.cancelRecentsAnimation(restoreHomeStackPosition
5312                        ? REORDER_MOVE_TO_ORIGINAL_POSITION
5313                        : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation");
5314            }
5315        } finally {
5316            Binder.restoreCallingIdentity(origId);
5317        }
5318    }
5319
5320    @Override
5321    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
5322            throws RemoteException {
5323        Slog.i(TAG, "Activity tried to startVoiceInteraction");
5324        synchronized (this) {
5325            ActivityRecord activity = getFocusedStack().getTopActivity();
5326            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
5327                throw new SecurityException("Only focused activity can call startVoiceInteraction");
5328            }
5329            if (mRunningVoice != null || activity.getTask().voiceSession != null
5330                    || activity.voiceSession != null) {
5331                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
5332                return;
5333            }
5334            if (activity.pendingVoiceInteractionStart) {
5335                Slog.w(TAG, "Pending start of voice interaction already.");
5336                return;
5337            }
5338            activity.pendingVoiceInteractionStart = true;
5339        }
5340        LocalServices.getService(VoiceInteractionManagerInternal.class)
5341                .startLocalVoiceInteraction(callingActivity, options);
5342    }
5343
5344    @Override
5345    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
5346        LocalServices.getService(VoiceInteractionManagerInternal.class)
5347                .stopLocalVoiceInteraction(callingActivity);
5348    }
5349
5350    @Override
5351    public boolean supportsLocalVoiceInteraction() throws RemoteException {
5352        return LocalServices.getService(VoiceInteractionManagerInternal.class)
5353                .supportsLocalVoiceInteraction();
5354    }
5355
5356    @GuardedBy("this")
5357    void onLocalVoiceInteractionStartedLocked(IBinder activity,
5358            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5359        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
5360        if (activityToCallback == null) return;
5361        activityToCallback.setVoiceSessionLocked(voiceSession);
5362
5363        // Inform the activity
5364        try {
5365            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
5366                    voiceInteractor);
5367            long token = Binder.clearCallingIdentity();
5368            try {
5369                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
5370            } finally {
5371                Binder.restoreCallingIdentity(token);
5372            }
5373            // TODO: VI Should we cache the activity so that it's easier to find later
5374            // rather than scan through all the stacks and activities?
5375        } catch (RemoteException re) {
5376            activityToCallback.clearVoiceSessionLocked();
5377            // TODO: VI Should this terminate the voice session?
5378        }
5379    }
5380
5381    @Override
5382    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
5383        synchronized (this) {
5384            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
5385                if (keepAwake) {
5386                    mVoiceWakeLock.acquire();
5387                } else {
5388                    mVoiceWakeLock.release();
5389                }
5390            }
5391        }
5392    }
5393
5394    @Override
5395    public boolean startNextMatchingActivity(IBinder callingActivity,
5396            Intent intent, Bundle bOptions) {
5397        // Refuse possible leaked file descriptors
5398        if (intent != null && intent.hasFileDescriptors() == true) {
5399            throw new IllegalArgumentException("File descriptors passed in Intent");
5400        }
5401        SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
5402
5403        synchronized (this) {
5404            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
5405            if (r == null) {
5406                SafeActivityOptions.abort(options);
5407                return false;
5408            }
5409            if (r.app == null || r.app.thread == null) {
5410                // The caller is not running...  d'oh!
5411                SafeActivityOptions.abort(options);
5412                return false;
5413            }
5414            intent = new Intent(intent);
5415            // The caller is not allowed to change the data.
5416            intent.setDataAndType(r.intent.getData(), r.intent.getType());
5417            // And we are resetting to find the next component...
5418            intent.setComponent(null);
5419
5420            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5421
5422            ActivityInfo aInfo = null;
5423            try {
5424                List<ResolveInfo> resolves =
5425                    AppGlobals.getPackageManager().queryIntentActivities(
5426                            intent, r.resolvedType,
5427                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
5428                            UserHandle.getCallingUserId()).getList();
5429
5430                // Look for the original activity in the list...
5431                final int N = resolves != null ? resolves.size() : 0;
5432                for (int i=0; i<N; i++) {
5433                    ResolveInfo rInfo = resolves.get(i);
5434                    if (rInfo.activityInfo.packageName.equals(r.packageName)
5435                            && rInfo.activityInfo.name.equals(r.info.name)) {
5436                        // We found the current one...  the next matching is
5437                        // after it.
5438                        i++;
5439                        if (i<N) {
5440                            aInfo = resolves.get(i).activityInfo;
5441                        }
5442                        if (debug) {
5443                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
5444                                    + "/" + r.info.name);
5445                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
5446                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
5447                        }
5448                        break;
5449                    }
5450                }
5451            } catch (RemoteException e) {
5452            }
5453
5454            if (aInfo == null) {
5455                // Nobody who is next!
5456                SafeActivityOptions.abort(options);
5457                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
5458                return false;
5459            }
5460
5461            intent.setComponent(new ComponentName(
5462                    aInfo.applicationInfo.packageName, aInfo.name));
5463            intent.setFlags(intent.getFlags()&~(
5464                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
5465                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
5466                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
5467                    FLAG_ACTIVITY_NEW_TASK));
5468
5469            // Okay now we need to start the new activity, replacing the
5470            // currently running activity.  This is a little tricky because
5471            // we want to start the new one as if the current one is finished,
5472            // but not finish the current one first so that there is no flicker.
5473            // And thus...
5474            final boolean wasFinishing = r.finishing;
5475            r.finishing = true;
5476
5477            // Propagate reply information over to the new activity.
5478            final ActivityRecord resultTo = r.resultTo;
5479            final String resultWho = r.resultWho;
5480            final int requestCode = r.requestCode;
5481            r.resultTo = null;
5482            if (resultTo != null) {
5483                resultTo.removeResultsLocked(r, resultWho, requestCode);
5484            }
5485
5486            final long origId = Binder.clearCallingIdentity();
5487            // TODO(b/64750076): Check if calling pid should really be -1.
5488            final int res = mActivityStartController
5489                    .obtainStarter(intent, "startNextMatchingActivity")
5490                    .setCaller(r.app.thread)
5491                    .setResolvedType(r.resolvedType)
5492                    .setActivityInfo(aInfo)
5493                    .setResultTo(resultTo != null ? resultTo.appToken : null)
5494                    .setResultWho(resultWho)
5495                    .setRequestCode(requestCode)
5496                    .setCallingPid(-1)
5497                    .setCallingUid(r.launchedFromUid)
5498                    .setCallingPackage(r.launchedFromPackage)
5499                    .setRealCallingPid(-1)
5500                    .setRealCallingUid(r.launchedFromUid)
5501                    .setActivityOptions(options)
5502                    .execute();
5503            Binder.restoreCallingIdentity(origId);
5504
5505            r.finishing = wasFinishing;
5506            if (res != ActivityManager.START_SUCCESS) {
5507                return false;
5508            }
5509            return true;
5510        }
5511    }
5512
5513    @Override
5514    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
5515        enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
5516                "startActivityFromRecents()");
5517
5518        final int callingPid = Binder.getCallingPid();
5519        final int callingUid = Binder.getCallingUid();
5520        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
5521        final long origId = Binder.clearCallingIdentity();
5522        try {
5523            synchronized (this) {
5524                return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
5525                        safeOptions);
5526            }
5527        } finally {
5528            Binder.restoreCallingIdentity(origId);
5529        }
5530    }
5531
5532    @Override
5533    public final int startActivities(IApplicationThread caller, String callingPackage,
5534            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
5535            int userId) {
5536        final String reason = "startActivities";
5537        enforceNotIsolatedCaller(reason);
5538        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5539                userId, false, ALLOW_FULL_ONLY, reason, null);
5540        // TODO: Switch to user app stacks here.
5541        int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
5542                intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
5543                reason);
5544        return ret;
5545    }
5546
5547    @Override
5548    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
5549        synchronized (this) {
5550            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5551            if (r == null) {
5552                return;
5553            }
5554            r.reportFullyDrawnLocked(restoredFromBundle);
5555        }
5556    }
5557
5558    @Override
5559    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
5560        synchronized (this) {
5561            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5562            if (r == null) {
5563                return;
5564            }
5565            final long origId = Binder.clearCallingIdentity();
5566            try {
5567                r.setRequestedOrientation(requestedOrientation);
5568            } finally {
5569                Binder.restoreCallingIdentity(origId);
5570            }
5571        }
5572    }
5573
5574    @Override
5575    public int getRequestedOrientation(IBinder token) {
5576        synchronized (this) {
5577            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5578            if (r == null) {
5579                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5580            }
5581            return r.getRequestedOrientation();
5582        }
5583    }
5584
5585    /**
5586     * This is the internal entry point for handling Activity.finish().
5587     *
5588     * @param token The Binder token referencing the Activity we want to finish.
5589     * @param resultCode Result code, if any, from this Activity.
5590     * @param resultData Result data (Intent), if any, from this Activity.
5591     * @param finishTask Whether to finish the task associated with this Activity.
5592     *
5593     * @return Returns true if the activity successfully finished, or false if it is still running.
5594     */
5595    @Override
5596    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5597            int finishTask) {
5598        // Refuse possible leaked file descriptors
5599        if (resultData != null && resultData.hasFileDescriptors() == true) {
5600            throw new IllegalArgumentException("File descriptors passed in Intent");
5601        }
5602
5603        synchronized(this) {
5604            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5605            if (r == null) {
5606                return true;
5607            }
5608            // Keep track of the root activity of the task before we finish it
5609            TaskRecord tr = r.getTask();
5610            ActivityRecord rootR = tr.getRootActivity();
5611            if (rootR == null) {
5612                Slog.w(TAG, "Finishing task with all activities already finished");
5613            }
5614            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5615            // finish.
5616            if (mLockTaskController.activityBlockedFromFinish(r)) {
5617                return false;
5618            }
5619
5620            if (mController != null) {
5621                // Find the first activity that is not finishing.
5622                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5623                if (next != null) {
5624                    // ask watcher if this is allowed
5625                    boolean resumeOK = true;
5626                    try {
5627                        resumeOK = mController.activityResuming(next.packageName);
5628                    } catch (RemoteException e) {
5629                        mController = null;
5630                        Watchdog.getInstance().setActivityController(null);
5631                    }
5632
5633                    if (!resumeOK) {
5634                        Slog.i(TAG, "Not finishing activity because controller resumed");
5635                        return false;
5636                    }
5637                }
5638            }
5639            final long origId = Binder.clearCallingIdentity();
5640            try {
5641                boolean res;
5642                final boolean finishWithRootActivity =
5643                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5644                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5645                        || (finishWithRootActivity && r == rootR)) {
5646                    // If requested, remove the task that is associated to this activity only if it
5647                    // was the root activity in the task. The result code and data is ignored
5648                    // because we don't support returning them across task boundaries. Also, to
5649                    // keep backwards compatibility we remove the task from recents when finishing
5650                    // task with root activity.
5651                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5652                            finishWithRootActivity, "finish-activity");
5653                    if (!res) {
5654                        Slog.i(TAG, "Removing task failed to finish activity");
5655                    }
5656                } else {
5657                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5658                            resultData, "app-request", true);
5659                    if (!res) {
5660                        Slog.i(TAG, "Failed to finish by app-request");
5661                    }
5662                }
5663                return res;
5664            } finally {
5665                Binder.restoreCallingIdentity(origId);
5666            }
5667        }
5668    }
5669
5670    @Override
5671    public final void finishHeavyWeightApp() {
5672        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5673                != PackageManager.PERMISSION_GRANTED) {
5674            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5675                    + Binder.getCallingPid()
5676                    + ", uid=" + Binder.getCallingUid()
5677                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5678            Slog.w(TAG, msg);
5679            throw new SecurityException(msg);
5680        }
5681
5682        synchronized(this) {
5683            final ProcessRecord proc = mHeavyWeightProcess;
5684            if (proc == null) {
5685                return;
5686            }
5687
5688            ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
5689            for (int i = 0; i < activities.size(); i++) {
5690                ActivityRecord r = activities.get(i);
5691                if (!r.finishing && r.isInStackLocked()) {
5692                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5693                            null, "finish-heavy", true);
5694                }
5695            }
5696
5697            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5698                    proc.userId, 0));
5699            mHeavyWeightProcess = null;
5700        }
5701    }
5702
5703    @Override
5704    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5705            String message) {
5706        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5707                != PackageManager.PERMISSION_GRANTED) {
5708            String msg = "Permission Denial: crashApplication() from pid="
5709                    + Binder.getCallingPid()
5710                    + ", uid=" + Binder.getCallingUid()
5711                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5712            Slog.w(TAG, msg);
5713            throw new SecurityException(msg);
5714        }
5715
5716        synchronized(this) {
5717            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5718        }
5719    }
5720
5721    @Override
5722    public final void finishSubActivity(IBinder token, String resultWho,
5723            int requestCode) {
5724        synchronized(this) {
5725            final long origId = Binder.clearCallingIdentity();
5726            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5727            if (r != null) {
5728                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5729            }
5730            Binder.restoreCallingIdentity(origId);
5731        }
5732    }
5733
5734    @Override
5735    public boolean finishActivityAffinity(IBinder token) {
5736        synchronized(this) {
5737            final long origId = Binder.clearCallingIdentity();
5738            try {
5739                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5740                if (r == null) {
5741                    return false;
5742                }
5743
5744                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5745                // can finish.
5746                final TaskRecord task = r.getTask();
5747                if (mLockTaskController.activityBlockedFromFinish(r)) {
5748                    return false;
5749                }
5750                return task.getStack().finishActivityAffinityLocked(r);
5751            } finally {
5752                Binder.restoreCallingIdentity(origId);
5753            }
5754        }
5755    }
5756
5757    @Override
5758    public void finishVoiceTask(IVoiceInteractionSession session) {
5759        synchronized (this) {
5760            final long origId = Binder.clearCallingIdentity();
5761            try {
5762                // TODO: VI Consider treating local voice interactions and voice tasks
5763                // differently here
5764                mStackSupervisor.finishVoiceTask(session);
5765            } finally {
5766                Binder.restoreCallingIdentity(origId);
5767            }
5768        }
5769
5770    }
5771
5772    @Override
5773    public boolean releaseActivityInstance(IBinder token) {
5774        synchronized(this) {
5775            final long origId = Binder.clearCallingIdentity();
5776            try {
5777                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5778                if (r == null) {
5779                    return false;
5780                }
5781                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5782            } finally {
5783                Binder.restoreCallingIdentity(origId);
5784            }
5785        }
5786    }
5787
5788    @Override
5789    public void releaseSomeActivities(IApplicationThread appInt) {
5790        synchronized(this) {
5791            final long origId = Binder.clearCallingIdentity();
5792            try {
5793                ProcessRecord app = getRecordForAppLocked(appInt);
5794                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5795            } finally {
5796                Binder.restoreCallingIdentity(origId);
5797            }
5798        }
5799    }
5800
5801    @Override
5802    public boolean willActivityBeVisible(IBinder token) {
5803        synchronized(this) {
5804            ActivityStack stack = ActivityRecord.getStackLocked(token);
5805            if (stack != null) {
5806                return stack.willActivityBeVisibleLocked(token);
5807            }
5808            return false;
5809        }
5810    }
5811
5812    @Override
5813    public void overridePendingTransition(IBinder token, String packageName,
5814            int enterAnim, int exitAnim) {
5815        synchronized(this) {
5816            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5817            if (self == null) {
5818                return;
5819            }
5820
5821            final long origId = Binder.clearCallingIdentity();
5822
5823            if (self.isState(ActivityState.RESUMED, ActivityState.PAUSING)) {
5824                mWindowManager.overridePendingAppTransition(packageName,
5825                        enterAnim, exitAnim, null);
5826            }
5827
5828            Binder.restoreCallingIdentity(origId);
5829        }
5830    }
5831
5832    /**
5833     * Main function for removing an existing process from the activity manager
5834     * as a result of that process going away.  Clears out all connections
5835     * to the process.
5836     */
5837    @GuardedBy("this")
5838    private final void handleAppDiedLocked(ProcessRecord app,
5839            boolean restarting, boolean allowRestart) {
5840        int pid = app.pid;
5841        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5842                false /*replacingPid*/);
5843        if (!kept && !restarting) {
5844            removeLruProcessLocked(app);
5845            if (pid > 0) {
5846                ProcessList.remove(pid);
5847            }
5848        }
5849
5850        if (mProfileProc == app) {
5851            clearProfilerLocked();
5852        }
5853
5854        // Remove this application's activities from active lists.
5855        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5856
5857        app.clearRecentTasks();
5858
5859        app.activities.clear();
5860
5861        if (app.instr != null) {
5862            Slog.w(TAG, "Crash of app " + app.processName
5863                  + " running instrumentation " + app.instr.mClass);
5864            Bundle info = new Bundle();
5865            info.putString("shortMsg", "Process crashed.");
5866            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5867        }
5868
5869        mWindowManager.deferSurfaceLayout();
5870        try {
5871            if (!restarting && hasVisibleActivities
5872                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5873                // If there was nothing to resume, and we are not already restarting this process, but
5874                // there is a visible activity that is hosted by the process...  then make sure all
5875                // visible activities are running, taking care of restarting this process.
5876                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5877            }
5878        } finally {
5879            mWindowManager.continueSurfaceLayout();
5880        }
5881    }
5882
5883    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5884        final IBinder threadBinder = thread.asBinder();
5885        // Find the application record.
5886        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5887            final ProcessRecord rec = mLruProcesses.get(i);
5888            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5889                return i;
5890            }
5891        }
5892        return -1;
5893    }
5894
5895    ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
5896        if (thread == null) {
5897            return null;
5898        }
5899
5900        int appIndex = getLRURecordIndexForAppLocked(thread);
5901        if (appIndex >= 0) {
5902            return mLruProcesses.get(appIndex);
5903        }
5904
5905        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5906        // double-check that.
5907        final IBinder threadBinder = thread.asBinder();
5908        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5909        for (int i = pmap.size()-1; i >= 0; i--) {
5910            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5911            for (int j = procs.size()-1; j >= 0; j--) {
5912                final ProcessRecord proc = procs.valueAt(j);
5913                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5914                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5915                            + proc);
5916                    return proc;
5917                }
5918            }
5919        }
5920
5921        return null;
5922    }
5923
5924    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5925        // If there are no longer any background processes running,
5926        // and the app that died was not running instrumentation,
5927        // then tell everyone we are now low on memory.
5928        boolean haveBg = false;
5929        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5930            ProcessRecord rec = mLruProcesses.get(i);
5931            if (rec.thread != null
5932                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5933                haveBg = true;
5934                break;
5935            }
5936        }
5937
5938        if (!haveBg) {
5939            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5940            if (doReport) {
5941                long now = SystemClock.uptimeMillis();
5942                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5943                    doReport = false;
5944                } else {
5945                    mLastMemUsageReportTime = now;
5946                }
5947            }
5948            final ArrayList<ProcessMemInfo> memInfos
5949                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5950            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5951            long now = SystemClock.uptimeMillis();
5952            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5953                ProcessRecord rec = mLruProcesses.get(i);
5954                if (rec == dyingProc || rec.thread == null) {
5955                    continue;
5956                }
5957                if (doReport) {
5958                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5959                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5960                }
5961                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5962                    // The low memory report is overriding any current
5963                    // state for a GC request.  Make sure to do
5964                    // heavy/important/visible/foreground processes first.
5965                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5966                        rec.lastRequestedGc = 0;
5967                    } else {
5968                        rec.lastRequestedGc = rec.lastLowMemory;
5969                    }
5970                    rec.reportLowMemory = true;
5971                    rec.lastLowMemory = now;
5972                    mProcessesToGc.remove(rec);
5973                    addProcessToGcListLocked(rec);
5974                }
5975            }
5976            if (doReport) {
5977                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5978                mHandler.sendMessage(msg);
5979            }
5980            scheduleAppGcsLocked();
5981        }
5982    }
5983
5984    @GuardedBy("this")
5985    final void appDiedLocked(ProcessRecord app) {
5986       appDiedLocked(app, app.pid, app.thread, false);
5987    }
5988
5989    @GuardedBy("this")
5990    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5991            boolean fromBinderDied) {
5992        // First check if this ProcessRecord is actually active for the pid.
5993        synchronized (mPidsSelfLocked) {
5994            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5995            if (curProc != app) {
5996                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5997                return;
5998            }
5999        }
6000
6001        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6002        synchronized (stats) {
6003            stats.noteProcessDiedLocked(app.info.uid, pid);
6004        }
6005
6006        if (!app.killed) {
6007            if (!fromBinderDied) {
6008                killProcessQuiet(pid);
6009            }
6010            killProcessGroup(app.uid, pid);
6011            app.killed = true;
6012        }
6013
6014        // Clean up already done if the process has been re-started.
6015        if (app.pid == pid && app.thread != null &&
6016                app.thread.asBinder() == thread.asBinder()) {
6017            boolean doLowMem = app.instr == null;
6018            boolean doOomAdj = doLowMem;
6019            if (!app.killedByAm) {
6020                reportUidInfoMessageLocked(TAG,
6021                        "Process " + app.processName + " (pid " + pid + ") has died: "
6022                                + ProcessList.makeOomAdjString(app.setAdj)
6023                                + ProcessList.makeProcStateString(app.setProcState), app.info.uid);
6024                mAllowLowerMemLevel = true;
6025            } else {
6026                // Note that we always want to do oom adj to update our state with the
6027                // new number of procs.
6028                mAllowLowerMemLevel = false;
6029                doLowMem = false;
6030            }
6031            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
6032                    app.setAdj, app.setProcState);
6033            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
6034                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
6035            handleAppDiedLocked(app, false, true);
6036
6037            if (doOomAdj) {
6038                updateOomAdjLocked();
6039            }
6040            if (doLowMem) {
6041                doLowMemReportIfNeededLocked(app);
6042            }
6043        } else if (app.pid != pid) {
6044            // A new process has already been started.
6045            reportUidInfoMessageLocked(TAG,
6046                    "Process " + app.processName + " (pid " + pid
6047                            + ") has died and restarted (pid " + app.pid + ").", app.info.uid);
6048            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
6049        } else if (DEBUG_PROCESSES) {
6050            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
6051                    + thread.asBinder());
6052        }
6053
6054        // On the device which doesn't have Cgroup, log LmkStateChanged which is used as a signal
6055        // for pulling memory stats of other running processes when this process died.
6056        if (!hasMemcg()) {
6057            StatsLog.write(StatsLog.APP_DIED, SystemClock.elapsedRealtime());
6058        }
6059    }
6060
6061    /**
6062     * If a stack trace dump file is configured, dump process stack traces.
6063     * @param clearTraces causes the dump file to be erased prior to the new
6064     *    traces being written, if true; when false, the new traces will be
6065     *    appended to any existing file content.
6066     * @param firstPids of dalvik VM processes to dump stack traces for first
6067     * @param lastPids of dalvik VM processes to dump stack traces for last
6068     * @param nativePids optional list of native pids to dump stack crawls
6069     */
6070    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
6071            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
6072            ArrayList<Integer> nativePids) {
6073        ArrayList<Integer> extraPids = null;
6074
6075        // Measure CPU usage as soon as we're called in order to get a realistic sampling
6076        // of the top users at the time of the request.
6077        if (processCpuTracker != null) {
6078            processCpuTracker.init();
6079            try {
6080                Thread.sleep(200);
6081            } catch (InterruptedException ignored) {
6082            }
6083
6084            processCpuTracker.update();
6085
6086            // We'll take the stack crawls of just the top apps using CPU.
6087            final int N = processCpuTracker.countWorkingStats();
6088            extraPids = new ArrayList<>();
6089            for (int i = 0; i < N && extraPids.size() < 5; i++) {
6090                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
6091                if (lastPids.indexOfKey(stats.pid) >= 0) {
6092                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
6093
6094                    extraPids.add(stats.pid);
6095                } else if (DEBUG_ANR) {
6096                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
6097                            + stats.pid);
6098                }
6099            }
6100        }
6101
6102        boolean useTombstonedForJavaTraces = false;
6103        File tracesFile;
6104
6105        final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
6106        if (tracesDirProp.isEmpty()) {
6107            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
6108            // dumping scheme. All traces are written to a global trace file (usually
6109            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
6110            // the file if requested.
6111            //
6112            // This mode of operation will be removed in the near future.
6113
6114
6115            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6116            if (globalTracesPath.isEmpty()) {
6117                Slog.w(TAG, "dumpStackTraces: no trace path configured");
6118                return null;
6119            }
6120
6121            tracesFile = new File(globalTracesPath);
6122            try {
6123                if (clearTraces && tracesFile.exists()) {
6124                    tracesFile.delete();
6125                }
6126
6127                tracesFile.createNewFile();
6128                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
6129            } catch (IOException e) {
6130                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
6131                return null;
6132            }
6133        } else {
6134            File tracesDir = new File(tracesDirProp);
6135            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
6136            // Each set of ANR traces is written to a separate file and dumpstate will process
6137            // all such files and add them to a captured bug report if they're recent enough.
6138            maybePruneOldTraces(tracesDir);
6139
6140            // NOTE: We should consider creating the file in native code atomically once we've
6141            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
6142            // can be removed.
6143            tracesFile = createAnrDumpFile(tracesDir);
6144            if (tracesFile == null) {
6145                return null;
6146            }
6147
6148            useTombstonedForJavaTraces = true;
6149        }
6150
6151        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
6152                useTombstonedForJavaTraces);
6153        return tracesFile;
6154    }
6155
6156    @GuardedBy("ActivityManagerService.class")
6157    private static SimpleDateFormat sAnrFileDateFormat;
6158
6159    private static synchronized File createAnrDumpFile(File tracesDir) {
6160        if (sAnrFileDateFormat == null) {
6161            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
6162        }
6163
6164        final String formattedDate = sAnrFileDateFormat.format(new Date());
6165        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
6166
6167        try {
6168            if (anrFile.createNewFile()) {
6169                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
6170                return anrFile;
6171            } else {
6172                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
6173            }
6174        } catch (IOException ioe) {
6175            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
6176        }
6177
6178        return null;
6179    }
6180
6181    /**
6182     * Prune all trace files that are more than a day old.
6183     *
6184     * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
6185     * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
6186     * since it's the system_server that creates trace files for most ANRs.
6187     */
6188    private static void maybePruneOldTraces(File tracesDir) {
6189        final long now = System.currentTimeMillis();
6190        final File[] traceFiles = tracesDir.listFiles();
6191
6192        if (traceFiles != null) {
6193            for (File file : traceFiles) {
6194                if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
6195                    if (!file.delete()) {
6196                        Slog.w(TAG, "Unable to prune stale trace file: " + file);
6197                    }
6198                }
6199            }
6200        }
6201    }
6202
6203    /**
6204     * Legacy code, do not use. Existing users will be deleted.
6205     *
6206     * @deprecated
6207     */
6208    @Deprecated
6209    public static class DumpStackFileObserver extends FileObserver {
6210        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
6211        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
6212
6213        private final String mTracesPath;
6214        private boolean mClosed;
6215
6216        public DumpStackFileObserver(String tracesPath) {
6217            super(tracesPath, FileObserver.CLOSE_WRITE);
6218            mTracesPath = tracesPath;
6219        }
6220
6221        @Override
6222        public synchronized void onEvent(int event, String path) {
6223            mClosed = true;
6224            notify();
6225        }
6226
6227        public long dumpWithTimeout(int pid, long timeout) {
6228            sendSignal(pid, SIGNAL_QUIT);
6229            final long start = SystemClock.elapsedRealtime();
6230
6231            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
6232            synchronized (this) {
6233                try {
6234                    wait(waitTime); // Wait for traces file to be closed.
6235                } catch (InterruptedException e) {
6236                    Slog.wtf(TAG, e);
6237                }
6238            }
6239
6240            // This avoids a corner case of passing a negative time to the native
6241            // trace in case we've already hit the overall timeout.
6242            final long timeWaited = SystemClock.elapsedRealtime() - start;
6243            if (timeWaited >= timeout) {
6244                return timeWaited;
6245            }
6246
6247            if (!mClosed) {
6248                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
6249                       ". Attempting native stack collection.");
6250
6251                final long nativeDumpTimeoutMs = Math.min(
6252                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
6253
6254                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
6255                        (int) (nativeDumpTimeoutMs / 1000));
6256            }
6257
6258            final long end = SystemClock.elapsedRealtime();
6259            mClosed = false;
6260
6261            return (end - start);
6262        }
6263    }
6264
6265    /**
6266     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
6267     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
6268     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
6269     * attempting to obtain native traces in the case of a failure. Returns the total time spent
6270     * capturing traces.
6271     */
6272    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
6273        final long timeStart = SystemClock.elapsedRealtime();
6274        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
6275            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
6276                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
6277        }
6278
6279        return SystemClock.elapsedRealtime() - timeStart;
6280    }
6281
6282    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
6283            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
6284            boolean useTombstonedForJavaTraces) {
6285
6286        // We don't need any sort of inotify based monitoring when we're dumping traces via
6287        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
6288        // control of all writes to the file in question.
6289        final DumpStackFileObserver observer;
6290        if (useTombstonedForJavaTraces) {
6291            observer = null;
6292        } else {
6293            // Use a FileObserver to detect when traces finish writing.
6294            // The order of traces is considered important to maintain for legibility.
6295            observer = new DumpStackFileObserver(tracesFile);
6296        }
6297
6298        // We must complete all stack dumps within 20 seconds.
6299        long remainingTime = 20 * 1000;
6300        try {
6301            if (observer != null) {
6302                observer.startWatching();
6303            }
6304
6305            // First collect all of the stacks of the most important pids.
6306            if (firstPids != null) {
6307                int num = firstPids.size();
6308                for (int i = 0; i < num; i++) {
6309                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
6310                            + firstPids.get(i));
6311                    final long timeTaken;
6312                    if (useTombstonedForJavaTraces) {
6313                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
6314                    } else {
6315                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
6316                    }
6317
6318                    remainingTime -= timeTaken;
6319                    if (remainingTime <= 0) {
6320                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
6321                            "); deadline exceeded.");
6322                        return;
6323                    }
6324
6325                    if (DEBUG_ANR) {
6326                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
6327                    }
6328                }
6329            }
6330
6331            // Next collect the stacks of the native pids
6332            if (nativePids != null) {
6333                for (int pid : nativePids) {
6334                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
6335                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
6336
6337                    final long start = SystemClock.elapsedRealtime();
6338                    Debug.dumpNativeBacktraceToFileTimeout(
6339                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
6340                    final long timeTaken = SystemClock.elapsedRealtime() - start;
6341
6342                    remainingTime -= timeTaken;
6343                    if (remainingTime <= 0) {
6344                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
6345                            "); deadline exceeded.");
6346                        return;
6347                    }
6348
6349                    if (DEBUG_ANR) {
6350                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
6351                    }
6352                }
6353            }
6354
6355            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
6356            if (extraPids != null) {
6357                for (int pid : extraPids) {
6358                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
6359
6360                    final long timeTaken;
6361                    if (useTombstonedForJavaTraces) {
6362                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
6363                    } else {
6364                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
6365                    }
6366
6367                    remainingTime -= timeTaken;
6368                    if (remainingTime <= 0) {
6369                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
6370                                "); deadline exceeded.");
6371                        return;
6372                    }
6373
6374                    if (DEBUG_ANR) {
6375                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
6376                    }
6377                }
6378            }
6379        } finally {
6380            if (observer != null) {
6381                observer.stopWatching();
6382            }
6383        }
6384    }
6385
6386    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
6387        if (true || Build.IS_USER) {
6388            return;
6389        }
6390        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6391        if (tracesPath == null || tracesPath.length() == 0) {
6392            return;
6393        }
6394
6395        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
6396        StrictMode.allowThreadDiskWrites();
6397        try {
6398            final File tracesFile = new File(tracesPath);
6399            final File tracesDir = tracesFile.getParentFile();
6400            final File tracesTmp = new File(tracesDir, "__tmp__");
6401            try {
6402                if (tracesFile.exists()) {
6403                    tracesTmp.delete();
6404                    tracesFile.renameTo(tracesTmp);
6405                }
6406                StringBuilder sb = new StringBuilder();
6407                Time tobj = new Time();
6408                tobj.set(System.currentTimeMillis());
6409                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
6410                sb.append(": ");
6411                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
6412                sb.append(" since ");
6413                sb.append(msg);
6414                FileOutputStream fos = new FileOutputStream(tracesFile);
6415                fos.write(sb.toString().getBytes());
6416                if (app == null) {
6417                    fos.write("\n*** No application process!".getBytes());
6418                }
6419                fos.close();
6420                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
6421            } catch (IOException e) {
6422                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
6423                return;
6424            }
6425
6426            if (app != null && app.pid > 0) {
6427                ArrayList<Integer> firstPids = new ArrayList<Integer>();
6428                firstPids.add(app.pid);
6429                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
6430            }
6431
6432            File lastTracesFile = null;
6433            File curTracesFile = null;
6434            for (int i=9; i>=0; i--) {
6435                String name = String.format(Locale.US, "slow%02d.txt", i);
6436                curTracesFile = new File(tracesDir, name);
6437                if (curTracesFile.exists()) {
6438                    if (lastTracesFile != null) {
6439                        curTracesFile.renameTo(lastTracesFile);
6440                    } else {
6441                        curTracesFile.delete();
6442                    }
6443                }
6444                lastTracesFile = curTracesFile;
6445            }
6446            tracesFile.renameTo(curTracesFile);
6447            if (tracesTmp.exists()) {
6448                tracesTmp.renameTo(tracesFile);
6449            }
6450        } finally {
6451            StrictMode.setThreadPolicy(oldPolicy);
6452        }
6453    }
6454
6455    @GuardedBy("this")
6456    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
6457        if (!mLaunchWarningShown) {
6458            mLaunchWarningShown = true;
6459            mUiHandler.post(new Runnable() {
6460                @Override
6461                public void run() {
6462                    synchronized (ActivityManagerService.this) {
6463                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
6464                        d.show();
6465                        mUiHandler.postDelayed(new Runnable() {
6466                            @Override
6467                            public void run() {
6468                                synchronized (ActivityManagerService.this) {
6469                                    d.dismiss();
6470                                    mLaunchWarningShown = false;
6471                                }
6472                            }
6473                        }, 4000);
6474                    }
6475                }
6476            });
6477        }
6478    }
6479
6480    @Override
6481    public boolean clearApplicationUserData(final String packageName, boolean keepState,
6482            final IPackageDataObserver observer, int userId) {
6483        enforceNotIsolatedCaller("clearApplicationUserData");
6484        int uid = Binder.getCallingUid();
6485        int pid = Binder.getCallingPid();
6486        final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
6487                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
6488
6489        final ApplicationInfo appInfo;
6490        final boolean isInstantApp;
6491
6492        long callingId = Binder.clearCallingIdentity();
6493        try {
6494            IPackageManager pm = AppGlobals.getPackageManager();
6495            synchronized(this) {
6496                // Instant packages are not protected
6497                if (getPackageManagerInternalLocked().isPackageDataProtected(
6498                        resolvedUserId, packageName)) {
6499                    throw new SecurityException(
6500                            "Cannot clear data for a protected package: " + packageName);
6501                }
6502
6503                ApplicationInfo applicationInfo = null;
6504                try {
6505                    applicationInfo = pm.getApplicationInfo(packageName,
6506                            MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
6507                } catch (RemoteException e) {
6508                    /* ignore */
6509                }
6510                appInfo = applicationInfo;
6511
6512                final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
6513
6514                if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
6515                        pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
6516                    throw new SecurityException("PID " + pid + " does not have permission "
6517                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
6518                            + " of package " + packageName);
6519                }
6520
6521                final boolean hasInstantMetadata = getPackageManagerInternalLocked()
6522                        .hasInstantApplicationMetadata(packageName, resolvedUserId);
6523                final boolean isUninstalledAppWithoutInstantMetadata =
6524                        (appInfo == null && !hasInstantMetadata);
6525                isInstantApp = (appInfo != null && appInfo.isInstantApp())
6526                        || hasInstantMetadata;
6527                final boolean canAccessInstantApps = checkComponentPermission(
6528                        permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
6529                        == PackageManager.PERMISSION_GRANTED;
6530
6531                if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
6532                        && !canAccessInstantApps)) {
6533                    Slog.w(TAG, "Invalid packageName: " + packageName);
6534                    if (observer != null) {
6535                        try {
6536                            observer.onRemoveCompleted(packageName, false);
6537                        } catch (RemoteException e) {
6538                            Slog.i(TAG, "Observer no longer exists.");
6539                        }
6540                    }
6541                    return false;
6542                }
6543
6544                if (appInfo != null) {
6545                    forceStopPackageLocked(packageName, appInfo.uid, "clear data");
6546                    mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
6547                }
6548            }
6549
6550            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
6551                @Override
6552                public void onRemoveCompleted(String packageName, boolean succeeded)
6553                        throws RemoteException {
6554                    if (appInfo != null) {
6555                        synchronized (ActivityManagerService.this) {
6556                            finishForceStopPackageLocked(packageName, appInfo.uid);
6557                        }
6558                    }
6559                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
6560                            Uri.fromParts("package", packageName, null));
6561                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6562                    intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6563                    intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6564                    if (isInstantApp) {
6565                        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6566                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6567                                null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6568                                resolvedUserId);
6569                    } else {
6570                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6571                                null, null, null, null, false, false, resolvedUserId);
6572                    }
6573
6574                    if (observer != null) {
6575                        observer.onRemoveCompleted(packageName, succeeded);
6576                    }
6577                }
6578            };
6579
6580            try {
6581                // Clear application user data
6582                pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6583
6584                if (appInfo != null) {
6585                    // Restore already established notification state and permission grants,
6586                    // so it told us to keep those intact -- it's about to emplace app data
6587                    // that is appropriate for those bits of system state.
6588                    if (!keepState) {
6589                        synchronized (this) {
6590                            // Remove all permissions granted from/to this package
6591                            removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true,
6592                                    false);
6593                        }
6594
6595                        // Reset notification state
6596                        INotificationManager inm = NotificationManager.getService();
6597                        inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6598                    }
6599
6600                    // Clear its scheduled jobs
6601                    JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
6602                    js.cancelJobsForUid(appInfo.uid, "clear data");
6603
6604                    // Clear its pending alarms
6605                    AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
6606                    ami.removeAlarmsForUid(appInfo.uid);
6607                }
6608            } catch (RemoteException e) {
6609            }
6610        } finally {
6611            Binder.restoreCallingIdentity(callingId);
6612        }
6613        return true;
6614    }
6615
6616    @Override
6617    public void killBackgroundProcesses(final String packageName, int userId) {
6618        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6619                != PackageManager.PERMISSION_GRANTED &&
6620                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6621                        != PackageManager.PERMISSION_GRANTED) {
6622            String msg = "Permission Denial: killBackgroundProcesses() from pid="
6623                    + Binder.getCallingPid()
6624                    + ", uid=" + Binder.getCallingUid()
6625                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6626            Slog.w(TAG, msg);
6627            throw new SecurityException(msg);
6628        }
6629
6630        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6631                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6632        final int[] userIds = mUserController.expandUserId(userId);
6633
6634        long callingId = Binder.clearCallingIdentity();
6635        try {
6636            IPackageManager pm = AppGlobals.getPackageManager();
6637            for (int targetUserId : userIds) {
6638                int appId = -1;
6639                try {
6640                    appId = UserHandle.getAppId(
6641                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6642                                    targetUserId));
6643                } catch (RemoteException e) {
6644                }
6645                if (appId == -1) {
6646                    Slog.w(TAG, "Invalid packageName: " + packageName);
6647                    return;
6648                }
6649                synchronized (this) {
6650                    killPackageProcessesLocked(packageName, appId, targetUserId,
6651                            ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6652                }
6653            }
6654        } finally {
6655            Binder.restoreCallingIdentity(callingId);
6656        }
6657    }
6658
6659    @Override
6660    public void killAllBackgroundProcesses() {
6661        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6662                != PackageManager.PERMISSION_GRANTED) {
6663            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6664                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6665                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6666            Slog.w(TAG, msg);
6667            throw new SecurityException(msg);
6668        }
6669
6670        final long callingId = Binder.clearCallingIdentity();
6671        try {
6672            synchronized (this) {
6673                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6674                final int NP = mProcessNames.getMap().size();
6675                for (int ip = 0; ip < NP; ip++) {
6676                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6677                    final int NA = apps.size();
6678                    for (int ia = 0; ia < NA; ia++) {
6679                        final ProcessRecord app = apps.valueAt(ia);
6680                        if (app.persistent) {
6681                            // We don't kill persistent processes.
6682                            continue;
6683                        }
6684                        if (app.removed) {
6685                            procs.add(app);
6686                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6687                            app.removed = true;
6688                            procs.add(app);
6689                        }
6690                    }
6691                }
6692
6693                final int N = procs.size();
6694                for (int i = 0; i < N; i++) {
6695                    removeProcessLocked(procs.get(i), false, true, "kill all background");
6696                }
6697
6698                mAllowLowerMemLevel = true;
6699
6700                updateOomAdjLocked();
6701                doLowMemReportIfNeededLocked(null);
6702            }
6703        } finally {
6704            Binder.restoreCallingIdentity(callingId);
6705        }
6706    }
6707
6708    /**
6709     * Kills all background processes, except those matching any of the
6710     * specified properties.
6711     *
6712     * @param minTargetSdk the target SDK version at or above which to preserve
6713     *                     processes, or {@code -1} to ignore the target SDK
6714     * @param maxProcState the process state at or below which to preserve
6715     *                     processes, or {@code -1} to ignore the process state
6716     */
6717    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6718        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6719                != PackageManager.PERMISSION_GRANTED) {
6720            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6721                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6722                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6723            Slog.w(TAG, msg);
6724            throw new SecurityException(msg);
6725        }
6726
6727        final long callingId = Binder.clearCallingIdentity();
6728        try {
6729            synchronized (this) {
6730                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6731                final int NP = mProcessNames.getMap().size();
6732                for (int ip = 0; ip < NP; ip++) {
6733                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6734                    final int NA = apps.size();
6735                    for (int ia = 0; ia < NA; ia++) {
6736                        final ProcessRecord app = apps.valueAt(ia);
6737                        if (app.removed) {
6738                            procs.add(app);
6739                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6740                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6741                            app.removed = true;
6742                            procs.add(app);
6743                        }
6744                    }
6745                }
6746
6747                final int N = procs.size();
6748                for (int i = 0; i < N; i++) {
6749                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6750                }
6751            }
6752        } finally {
6753            Binder.restoreCallingIdentity(callingId);
6754        }
6755    }
6756
6757    @Override
6758    public void forceStopPackage(final String packageName, int userId) {
6759        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6760                != PackageManager.PERMISSION_GRANTED) {
6761            String msg = "Permission Denial: forceStopPackage() from pid="
6762                    + Binder.getCallingPid()
6763                    + ", uid=" + Binder.getCallingUid()
6764                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6765            Slog.w(TAG, msg);
6766            throw new SecurityException(msg);
6767        }
6768        final int callingPid = Binder.getCallingPid();
6769        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6770                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6771        long callingId = Binder.clearCallingIdentity();
6772        try {
6773            IPackageManager pm = AppGlobals.getPackageManager();
6774            synchronized(this) {
6775                int[] users = userId == UserHandle.USER_ALL
6776                        ? mUserController.getUsers() : new int[] { userId };
6777                for (int user : users) {
6778                    if (getPackageManagerInternalLocked().isPackageStateProtected(
6779                            packageName, user)) {
6780                        Slog.w(TAG, "Ignoring request to force stop protected package "
6781                                + packageName + " u" + user);
6782                        return;
6783                    }
6784
6785                    int pkgUid = -1;
6786                    try {
6787                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6788                                user);
6789                    } catch (RemoteException e) {
6790                    }
6791                    if (pkgUid == -1) {
6792                        Slog.w(TAG, "Invalid packageName: " + packageName);
6793                        continue;
6794                    }
6795                    try {
6796                        pm.setPackageStoppedState(packageName, true, user);
6797                    } catch (RemoteException e) {
6798                    } catch (IllegalArgumentException e) {
6799                        Slog.w(TAG, "Failed trying to unstop package "
6800                                + packageName + ": " + e);
6801                    }
6802                    if (mUserController.isUserRunning(user, 0)) {
6803                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6804                        finishForceStopPackageLocked(packageName, pkgUid);
6805                    }
6806                }
6807            }
6808        } finally {
6809            Binder.restoreCallingIdentity(callingId);
6810        }
6811    }
6812
6813    @Override
6814    public void addPackageDependency(String packageName) {
6815        synchronized (this) {
6816            int callingPid = Binder.getCallingPid();
6817            if (callingPid == myPid()) {
6818                //  Yeah, um, no.
6819                return;
6820            }
6821            ProcessRecord proc;
6822            synchronized (mPidsSelfLocked) {
6823                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6824            }
6825            if (proc != null) {
6826                if (proc.pkgDeps == null) {
6827                    proc.pkgDeps = new ArraySet<String>(1);
6828                }
6829                proc.pkgDeps.add(packageName);
6830            }
6831        }
6832    }
6833
6834    /*
6835     * The pkg name and app id have to be specified.
6836     */
6837    @Override
6838    public void killApplication(String pkg, int appId, int userId, String reason) {
6839        if (pkg == null) {
6840            return;
6841        }
6842        // Make sure the uid is valid.
6843        if (appId < 0) {
6844            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6845            return;
6846        }
6847        int callerUid = Binder.getCallingUid();
6848        // Only the system server can kill an application
6849        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6850            // Post an aysnc message to kill the application
6851            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6852            msg.arg1 = appId;
6853            msg.arg2 = userId;
6854            Bundle bundle = new Bundle();
6855            bundle.putString("pkg", pkg);
6856            bundle.putString("reason", reason);
6857            msg.obj = bundle;
6858            mHandler.sendMessage(msg);
6859        } else {
6860            throw new SecurityException(callerUid + " cannot kill pkg: " +
6861                    pkg);
6862        }
6863    }
6864
6865    @Override
6866    public void closeSystemDialogs(String reason) {
6867        enforceNotIsolatedCaller("closeSystemDialogs");
6868
6869        final int pid = Binder.getCallingPid();
6870        final int uid = Binder.getCallingUid();
6871        final long origId = Binder.clearCallingIdentity();
6872        try {
6873            synchronized (this) {
6874                // Only allow this from foreground processes, so that background
6875                // applications can't abuse it to prevent system UI from being shown.
6876                if (uid >= FIRST_APPLICATION_UID) {
6877                    ProcessRecord proc;
6878                    synchronized (mPidsSelfLocked) {
6879                        proc = mPidsSelfLocked.get(pid);
6880                    }
6881                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6882                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6883                                + " from background process " + proc);
6884                        return;
6885                    }
6886                }
6887                closeSystemDialogsLocked(reason);
6888            }
6889        } finally {
6890            Binder.restoreCallingIdentity(origId);
6891        }
6892    }
6893
6894    @GuardedBy("this")
6895    void closeSystemDialogsLocked(String reason) {
6896        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6897        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6898                | Intent.FLAG_RECEIVER_FOREGROUND);
6899        if (reason != null) {
6900            intent.putExtra("reason", reason);
6901        }
6902        mWindowManager.closeSystemDialogs(reason);
6903
6904        mStackSupervisor.closeSystemDialogsLocked();
6905
6906        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6907                OP_NONE, null, false, false,
6908                -1, SYSTEM_UID, UserHandle.USER_ALL);
6909    }
6910
6911    @Override
6912    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6913        enforceNotIsolatedCaller("getProcessMemoryInfo");
6914        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6915        for (int i=pids.length-1; i>=0; i--) {
6916            ProcessRecord proc;
6917            int oomAdj;
6918            synchronized (this) {
6919                synchronized (mPidsSelfLocked) {
6920                    proc = mPidsSelfLocked.get(pids[i]);
6921                    oomAdj = proc != null ? proc.setAdj : 0;
6922                }
6923            }
6924            infos[i] = new Debug.MemoryInfo();
6925            long startTime = SystemClock.currentThreadTimeMillis();
6926            Debug.getMemoryInfo(pids[i], infos[i]);
6927            long endTime = SystemClock.currentThreadTimeMillis();
6928            if (proc != null) {
6929                synchronized (this) {
6930                    if (proc.thread != null && proc.setAdj == oomAdj) {
6931                        // Record this for posterity if the process has been stable.
6932                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6933                                infos[i].getTotalUss(), infos[i].getTotalRss(), false,
6934                                ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
6935                                proc.pkgList);
6936                    }
6937                }
6938            }
6939        }
6940        return infos;
6941    }
6942
6943    @Override
6944    public long[] getProcessPss(int[] pids) {
6945        enforceNotIsolatedCaller("getProcessPss");
6946        long[] pss = new long[pids.length];
6947        for (int i=pids.length-1; i>=0; i--) {
6948            ProcessRecord proc;
6949            int oomAdj;
6950            synchronized (this) {
6951                synchronized (mPidsSelfLocked) {
6952                    proc = mPidsSelfLocked.get(pids[i]);
6953                    oomAdj = proc != null ? proc.setAdj : 0;
6954                }
6955            }
6956            long[] tmpUss = new long[3];
6957            long startTime = SystemClock.currentThreadTimeMillis();
6958            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6959            long endTime = SystemClock.currentThreadTimeMillis();
6960            if (proc != null) {
6961                synchronized (this) {
6962                    if (proc.thread != null && proc.setAdj == oomAdj) {
6963                        // Record this for posterity if the process has been stable.
6964                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
6965                                ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
6966                    }
6967                }
6968            }
6969        }
6970        return pss;
6971    }
6972
6973    @Override
6974    public void killApplicationProcess(String processName, int uid) {
6975        if (processName == null) {
6976            return;
6977        }
6978
6979        int callerUid = Binder.getCallingUid();
6980        // Only the system server can kill an application
6981        if (callerUid == SYSTEM_UID) {
6982            synchronized (this) {
6983                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6984                if (app != null && app.thread != null) {
6985                    try {
6986                        app.thread.scheduleSuicide();
6987                    } catch (RemoteException e) {
6988                        // If the other end already died, then our work here is done.
6989                    }
6990                } else {
6991                    Slog.w(TAG, "Process/uid not found attempting kill of "
6992                            + processName + " / " + uid);
6993                }
6994            }
6995        } else {
6996            throw new SecurityException(callerUid + " cannot kill app process: " +
6997                    processName);
6998        }
6999    }
7000
7001    @GuardedBy("this")
7002    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
7003        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
7004                false, true, false, false, UserHandle.getUserId(uid), reason);
7005    }
7006
7007    @GuardedBy("this")
7008    private void finishForceStopPackageLocked(final String packageName, int uid) {
7009        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
7010                Uri.fromParts("package", packageName, null));
7011        if (!mProcessesReady) {
7012            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7013                    | Intent.FLAG_RECEIVER_FOREGROUND);
7014        }
7015        intent.putExtra(Intent.EXTRA_UID, uid);
7016        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
7017        broadcastIntentLocked(null, null, intent,
7018                null, null, 0, null, null, null, OP_NONE,
7019                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
7020    }
7021
7022
7023    @GuardedBy("this")
7024    private final boolean killPackageProcessesLocked(String packageName, int appId,
7025            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
7026            boolean doit, boolean evenPersistent, String reason) {
7027        ArrayList<ProcessRecord> procs = new ArrayList<>();
7028
7029        // Remove all processes this package may have touched: all with the
7030        // same UID (except for the system or root user), and all whose name
7031        // matches the package name.
7032        final int NP = mProcessNames.getMap().size();
7033        for (int ip=0; ip<NP; ip++) {
7034            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
7035            final int NA = apps.size();
7036            for (int ia=0; ia<NA; ia++) {
7037                ProcessRecord app = apps.valueAt(ia);
7038                if (app.persistent && !evenPersistent) {
7039                    // we don't kill persistent processes
7040                    continue;
7041                }
7042                if (app.removed) {
7043                    if (doit) {
7044                        procs.add(app);
7045                    }
7046                    continue;
7047                }
7048
7049                // Skip process if it doesn't meet our oom adj requirement.
7050                if (app.setAdj < minOomAdj) {
7051                    continue;
7052                }
7053
7054                // If no package is specified, we call all processes under the
7055                // give user id.
7056                if (packageName == null) {
7057                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
7058                        continue;
7059                    }
7060                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
7061                        continue;
7062                    }
7063                // Package has been specified, we want to hit all processes
7064                // that match it.  We need to qualify this by the processes
7065                // that are running under the specified app and user ID.
7066                } else {
7067                    final boolean isDep = app.pkgDeps != null
7068                            && app.pkgDeps.contains(packageName);
7069                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
7070                        continue;
7071                    }
7072                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
7073                        continue;
7074                    }
7075                    if (!app.pkgList.containsKey(packageName) && !isDep) {
7076                        continue;
7077                    }
7078                }
7079
7080                // Process has passed all conditions, kill it!
7081                if (!doit) {
7082                    return true;
7083                }
7084                app.removed = true;
7085                procs.add(app);
7086            }
7087        }
7088
7089        int N = procs.size();
7090        for (int i=0; i<N; i++) {
7091            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
7092        }
7093        updateOomAdjLocked();
7094        return N > 0;
7095    }
7096
7097    private void cleanupDisabledPackageComponentsLocked(
7098            String packageName, int userId, boolean killProcess, String[] changedClasses) {
7099
7100        Set<String> disabledClasses = null;
7101        boolean packageDisabled = false;
7102        IPackageManager pm = AppGlobals.getPackageManager();
7103
7104        if (changedClasses == null) {
7105            // Nothing changed...
7106            return;
7107        }
7108
7109        // Determine enable/disable state of the package and its components.
7110        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
7111        for (int i = changedClasses.length - 1; i >= 0; i--) {
7112            final String changedClass = changedClasses[i];
7113
7114            if (changedClass.equals(packageName)) {
7115                try {
7116                    // Entire package setting changed
7117                    enabled = pm.getApplicationEnabledSetting(packageName,
7118                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
7119                } catch (Exception e) {
7120                    // No such package/component; probably racing with uninstall.  In any
7121                    // event it means we have nothing further to do here.
7122                    return;
7123                }
7124                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
7125                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
7126                if (packageDisabled) {
7127                    // Entire package is disabled.
7128                    // No need to continue to check component states.
7129                    disabledClasses = null;
7130                    break;
7131                }
7132            } else {
7133                try {
7134                    enabled = pm.getComponentEnabledSetting(
7135                            new ComponentName(packageName, changedClass),
7136                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
7137                } catch (Exception e) {
7138                    // As above, probably racing with uninstall.
7139                    return;
7140                }
7141                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
7142                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
7143                    if (disabledClasses == null) {
7144                        disabledClasses = new ArraySet<>(changedClasses.length);
7145                    }
7146                    disabledClasses.add(changedClass);
7147                }
7148            }
7149        }
7150
7151        if (!packageDisabled && disabledClasses == null) {
7152            // Nothing to do here...
7153            return;
7154        }
7155
7156        // Clean-up disabled activities.
7157        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7158                packageName, disabledClasses, true, false, userId) && mBooted) {
7159            mStackSupervisor.resumeFocusedStackTopActivityLocked();
7160            mStackSupervisor.scheduleIdleLocked();
7161        }
7162
7163        // Clean-up disabled tasks
7164        mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
7165
7166        // Clean-up disabled services.
7167        mServices.bringDownDisabledPackageServicesLocked(
7168                packageName, disabledClasses, userId, false, killProcess, true);
7169
7170        // Clean-up disabled providers.
7171        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7172        mProviderMap.collectPackageProvidersLocked(
7173                packageName, disabledClasses, true, false, userId, providers);
7174        for (int i = providers.size() - 1; i >= 0; i--) {
7175            removeDyingProviderLocked(null, providers.get(i), true);
7176        }
7177
7178        // Clean-up disabled broadcast receivers.
7179        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7180            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7181                    packageName, disabledClasses, userId, true);
7182        }
7183
7184    }
7185
7186    final boolean clearBroadcastQueueForUserLocked(int userId) {
7187        boolean didSomething = false;
7188        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7189            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7190                    null, null, userId, true);
7191        }
7192        return didSomething;
7193    }
7194
7195    @GuardedBy("this")
7196    final boolean forceStopPackageLocked(String packageName, int appId,
7197            boolean callerWillRestart, boolean purgeCache, boolean doit,
7198            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
7199        int i;
7200
7201        if (userId == UserHandle.USER_ALL && packageName == null) {
7202            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
7203        }
7204
7205        if (appId < 0 && packageName != null) {
7206            try {
7207                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
7208                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
7209            } catch (RemoteException e) {
7210            }
7211        }
7212
7213        if (doit) {
7214            if (packageName != null) {
7215                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
7216                        + " user=" + userId + ": " + reason);
7217            } else {
7218                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
7219            }
7220
7221            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
7222        }
7223
7224        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
7225                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
7226                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
7227
7228        didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
7229
7230        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7231                packageName, null, doit, evenPersistent, userId)) {
7232            if (!doit) {
7233                return true;
7234            }
7235            didSomething = true;
7236        }
7237
7238        if (mServices.bringDownDisabledPackageServicesLocked(
7239                packageName, null, userId, evenPersistent, true, doit)) {
7240            if (!doit) {
7241                return true;
7242            }
7243            didSomething = true;
7244        }
7245
7246        if (packageName == null) {
7247            // Remove all sticky broadcasts from this user.
7248            mStickyBroadcasts.remove(userId);
7249        }
7250
7251        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7252        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
7253                userId, providers)) {
7254            if (!doit) {
7255                return true;
7256            }
7257            didSomething = true;
7258        }
7259        for (i = providers.size() - 1; i >= 0; i--) {
7260            removeDyingProviderLocked(null, providers.get(i), true);
7261        }
7262
7263        // Remove transient permissions granted from/to this package/user
7264        removeUriPermissionsForPackageLocked(packageName, userId, false, false);
7265
7266        if (doit) {
7267            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
7268                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7269                        packageName, null, userId, doit);
7270            }
7271        }
7272
7273        if (packageName == null || uninstalling) {
7274            // Remove pending intents.  For now we only do this when force
7275            // stopping users, because we have some problems when doing this
7276            // for packages -- app widgets are not currently cleaned up for
7277            // such packages, so they can be left with bad pending intents.
7278            if (mIntentSenderRecords.size() > 0) {
7279                Iterator<WeakReference<PendingIntentRecord>> it
7280                        = mIntentSenderRecords.values().iterator();
7281                while (it.hasNext()) {
7282                    WeakReference<PendingIntentRecord> wpir = it.next();
7283                    if (wpir == null) {
7284                        it.remove();
7285                        continue;
7286                    }
7287                    PendingIntentRecord pir = wpir.get();
7288                    if (pir == null) {
7289                        it.remove();
7290                        continue;
7291                    }
7292                    if (packageName == null) {
7293                        // Stopping user, remove all objects for the user.
7294                        if (pir.key.userId != userId) {
7295                            // Not the same user, skip it.
7296                            continue;
7297                        }
7298                    } else {
7299                        if (UserHandle.getAppId(pir.uid) != appId) {
7300                            // Different app id, skip it.
7301                            continue;
7302                        }
7303                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
7304                            // Different user, skip it.
7305                            continue;
7306                        }
7307                        if (!pir.key.packageName.equals(packageName)) {
7308                            // Different package, skip it.
7309                            continue;
7310                        }
7311                    }
7312                    if (!doit) {
7313                        return true;
7314                    }
7315                    didSomething = true;
7316                    it.remove();
7317                    makeIntentSenderCanceledLocked(pir);
7318                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
7319                        pir.key.activity.pendingResults.remove(pir.ref);
7320                    }
7321                }
7322            }
7323        }
7324
7325        if (doit) {
7326            if (purgeCache && packageName != null) {
7327                AttributeCache ac = AttributeCache.instance();
7328                if (ac != null) {
7329                    ac.removePackage(packageName);
7330                }
7331            }
7332            if (mBooted) {
7333                mStackSupervisor.resumeFocusedStackTopActivityLocked();
7334                mStackSupervisor.scheduleIdleLocked();
7335            }
7336        }
7337
7338        return didSomething;
7339    }
7340
7341    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
7342        return removeProcessNameLocked(name, uid, null);
7343    }
7344
7345    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
7346            final ProcessRecord expecting) {
7347        ProcessRecord old = mProcessNames.get(name, uid);
7348        // Only actually remove when the currently recorded value matches the
7349        // record that we expected; if it doesn't match then we raced with a
7350        // newly created process and we don't want to destroy the new one.
7351        if ((expecting == null) || (old == expecting)) {
7352            mProcessNames.remove(name, uid);
7353        }
7354        if (old != null && old.uidRecord != null) {
7355            old.uidRecord.numProcs--;
7356            if (old.uidRecord.numProcs == 0) {
7357                // No more processes using this uid, tell clients it is gone.
7358                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7359                        "No more processes in " + old.uidRecord);
7360                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
7361                EventLogTags.writeAmUidStopped(uid);
7362                mActiveUids.remove(uid);
7363                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
7364            }
7365            old.uidRecord = null;
7366        }
7367        mIsolatedProcesses.remove(uid);
7368        return old;
7369    }
7370
7371    private final void addProcessNameLocked(ProcessRecord proc) {
7372        // We shouldn't already have a process under this name, but just in case we
7373        // need to clean up whatever may be there now.
7374        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
7375        if (old == proc && proc.persistent) {
7376            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
7377            Slog.w(TAG, "Re-adding persistent process " + proc);
7378        } else if (old != null) {
7379            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
7380        }
7381        UidRecord uidRec = mActiveUids.get(proc.uid);
7382        if (uidRec == null) {
7383            uidRec = new UidRecord(proc.uid);
7384            // This is the first appearance of the uid, report it now!
7385            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7386                    "Creating new process uid: " + uidRec);
7387            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
7388                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
7389                uidRec.setWhitelist = uidRec.curWhitelist = true;
7390            }
7391            uidRec.updateHasInternetPermission();
7392            mActiveUids.put(proc.uid, uidRec);
7393            EventLogTags.writeAmUidRunning(uidRec.uid);
7394            noteUidProcessState(uidRec.uid, uidRec.curProcState);
7395        }
7396        proc.uidRecord = uidRec;
7397
7398        // Reset render thread tid if it was already set, so new process can set it again.
7399        proc.renderThreadTid = 0;
7400        uidRec.numProcs++;
7401        mProcessNames.put(proc.processName, proc.uid, proc);
7402        if (proc.isolated) {
7403            mIsolatedProcesses.put(proc.uid, proc);
7404        }
7405    }
7406
7407    @GuardedBy("this")
7408    boolean removeProcessLocked(ProcessRecord app,
7409            boolean callerWillRestart, boolean allowRestart, String reason) {
7410        final String name = app.processName;
7411        final int uid = app.uid;
7412        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
7413            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
7414
7415        ProcessRecord old = mProcessNames.get(name, uid);
7416        if (old != app) {
7417            // This process is no longer active, so nothing to do.
7418            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
7419            return false;
7420        }
7421        removeProcessNameLocked(name, uid);
7422        if (mHeavyWeightProcess == app) {
7423            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7424                    mHeavyWeightProcess.userId, 0));
7425            mHeavyWeightProcess = null;
7426        }
7427        boolean needRestart = false;
7428        if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
7429            int pid = app.pid;
7430            if (pid > 0) {
7431                synchronized (mPidsSelfLocked) {
7432                    mPidsSelfLocked.remove(pid);
7433                    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7434                }
7435                mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7436                if (app.isolated) {
7437                    mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7438                    getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
7439                }
7440            }
7441            boolean willRestart = false;
7442            if (app.persistent && !app.isolated) {
7443                if (!callerWillRestart) {
7444                    willRestart = true;
7445                } else {
7446                    needRestart = true;
7447                }
7448            }
7449            app.kill(reason, true);
7450            handleAppDiedLocked(app, willRestart, allowRestart);
7451            if (willRestart) {
7452                removeLruProcessLocked(app);
7453                addAppLocked(app.info, null, false, null /* ABI override */);
7454            }
7455        } else {
7456            mRemovedProcesses.add(app);
7457        }
7458
7459        return needRestart;
7460    }
7461
7462    @GuardedBy("this")
7463    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
7464        cleanupAppInLaunchingProvidersLocked(app, true);
7465        removeProcessLocked(app, false, true, "timeout publishing content providers");
7466    }
7467
7468    private final void processStartTimedOutLocked(ProcessRecord app) {
7469        final int pid = app.pid;
7470        boolean gone = false;
7471        synchronized (mPidsSelfLocked) {
7472            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
7473            if (knownApp != null && knownApp.thread == null) {
7474                mPidsSelfLocked.remove(pid);
7475                gone = true;
7476            }
7477        }
7478
7479        if (gone) {
7480            Slog.w(TAG, "Process " + app + " failed to attach");
7481            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
7482                    pid, app.uid, app.processName);
7483            removeProcessNameLocked(app.processName, app.uid);
7484            if (mHeavyWeightProcess == app) {
7485                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7486                        mHeavyWeightProcess.userId, 0));
7487                mHeavyWeightProcess = null;
7488            }
7489            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7490            // Take care of any launching providers waiting for this process.
7491            cleanupAppInLaunchingProvidersLocked(app, true);
7492            // Take care of any services that are waiting for the process.
7493            mServices.processStartTimedOutLocked(app);
7494            app.kill("start timeout", true);
7495            if (app.isolated) {
7496                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7497            }
7498            removeLruProcessLocked(app);
7499            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
7500                Slog.w(TAG, "Unattached app died before backup, skipping");
7501                mHandler.post(new Runnable() {
7502                @Override
7503                    public void run(){
7504                        try {
7505                            IBackupManager bm = IBackupManager.Stub.asInterface(
7506                                    ServiceManager.getService(Context.BACKUP_SERVICE));
7507                            bm.agentDisconnected(app.info.packageName);
7508                        } catch (RemoteException e) {
7509                            // Can't happen; the backup manager is local
7510                        }
7511                    }
7512                });
7513            }
7514            if (isPendingBroadcastProcessLocked(pid)) {
7515                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
7516                skipPendingBroadcastLocked(pid);
7517            }
7518        } else {
7519            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
7520        }
7521    }
7522
7523    @GuardedBy("this")
7524    private final boolean attachApplicationLocked(IApplicationThread thread,
7525            int pid, int callingUid, long startSeq) {
7526
7527        // Find the application record that is being attached...  either via
7528        // the pid if we are running in multiple processes, or just pull the
7529        // next app record if we are emulating process with anonymous threads.
7530        ProcessRecord app;
7531        long startTime = SystemClock.uptimeMillis();
7532        if (pid != MY_PID && pid >= 0) {
7533            synchronized (mPidsSelfLocked) {
7534                app = mPidsSelfLocked.get(pid);
7535            }
7536        } else {
7537            app = null;
7538        }
7539
7540        // It's possible that process called attachApplication before we got a chance to
7541        // update the internal state.
7542        if (app == null && startSeq > 0) {
7543            final ProcessRecord pending = mPendingStarts.get(startSeq);
7544            if (pending != null && pending.startUid == callingUid
7545                    && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
7546                            startSeq, true)) {
7547                app = pending;
7548            }
7549        }
7550
7551        if (app == null) {
7552            Slog.w(TAG, "No pending application record for pid " + pid
7553                    + " (IApplicationThread " + thread + "); dropping process");
7554            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
7555            if (pid > 0 && pid != MY_PID) {
7556                killProcessQuiet(pid);
7557                //TODO: killProcessGroup(app.info.uid, pid);
7558            } else {
7559                try {
7560                    thread.scheduleExit();
7561                } catch (Exception e) {
7562                    // Ignore exceptions.
7563                }
7564            }
7565            return false;
7566        }
7567
7568        // If this application record is still attached to a previous
7569        // process, clean it up now.
7570        if (app.thread != null) {
7571            handleAppDiedLocked(app, true, true);
7572        }
7573
7574        // Tell the process all about itself.
7575
7576        if (DEBUG_ALL) Slog.v(
7577                TAG, "Binding process pid " + pid + " to record " + app);
7578
7579        final String processName = app.processName;
7580        try {
7581            AppDeathRecipient adr = new AppDeathRecipient(
7582                    app, pid, thread);
7583            thread.asBinder().linkToDeath(adr, 0);
7584            app.deathRecipient = adr;
7585        } catch (RemoteException e) {
7586            app.resetPackageList(mProcessStats);
7587            startProcessLocked(app, "link fail", processName);
7588            return false;
7589        }
7590
7591        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
7592
7593        app.makeActive(thread, mProcessStats);
7594        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
7595        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
7596        app.forcingToImportant = null;
7597        updateProcessForegroundLocked(app, false, false);
7598        app.hasShownUi = false;
7599        app.debugging = false;
7600        app.cached = false;
7601        app.killedByAm = false;
7602        app.killed = false;
7603
7604
7605        // We carefully use the same state that PackageManager uses for
7606        // filtering, since we use this flag to decide if we need to install
7607        // providers when user is unlocked later
7608        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
7609
7610        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7611
7612        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
7613        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7614
7615        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7616            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7617            msg.obj = app;
7618            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7619        }
7620
7621        checkTime(startTime, "attachApplicationLocked: before bindApplication");
7622
7623        if (!normalMode) {
7624            Slog.i(TAG, "Launching preboot mode app: " + app);
7625        }
7626
7627        if (DEBUG_ALL) Slog.v(
7628            TAG, "New app record " + app
7629            + " thread=" + thread.asBinder() + " pid=" + pid);
7630        try {
7631            int testMode = ApplicationThreadConstants.DEBUG_OFF;
7632            if (mDebugApp != null && mDebugApp.equals(processName)) {
7633                testMode = mWaitForDebugger
7634                    ? ApplicationThreadConstants.DEBUG_WAIT
7635                    : ApplicationThreadConstants.DEBUG_ON;
7636                app.debugging = true;
7637                if (mDebugTransient) {
7638                    mDebugApp = mOrigDebugApp;
7639                    mWaitForDebugger = mOrigWaitForDebugger;
7640                }
7641            }
7642
7643            boolean enableTrackAllocation = false;
7644            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7645                enableTrackAllocation = true;
7646                mTrackAllocationApp = null;
7647            }
7648
7649            // If the app is being launched for restore or full backup, set it up specially
7650            boolean isRestrictedBackupMode = false;
7651            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7652                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7653                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7654                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7655                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7656            }
7657
7658            if (app.instr != null) {
7659                notifyPackageUse(app.instr.mClass.getPackageName(),
7660                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7661            }
7662            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7663                    + processName + " with config " + getGlobalConfiguration());
7664            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7665            app.compat = compatibilityInfoForPackageLocked(appInfo);
7666
7667            ProfilerInfo profilerInfo = null;
7668            String preBindAgent = null;
7669            if (mProfileApp != null && mProfileApp.equals(processName)) {
7670                mProfileProc = app;
7671                if (mProfilerInfo != null) {
7672                    // Send a profiler info object to the app if either a file is given, or
7673                    // an agent should be loaded at bind-time.
7674                    boolean needsInfo = mProfilerInfo.profileFile != null
7675                            || mProfilerInfo.attachAgentDuringBind;
7676                    profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7677                    if (mProfilerInfo.agent != null) {
7678                        preBindAgent = mProfilerInfo.agent;
7679                    }
7680                }
7681            } else if (app.instr != null && app.instr.mProfileFile != null) {
7682                profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7683                        null, false);
7684            }
7685            if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
7686                // We need to do a debuggable check here. See setAgentApp for why the check is
7687                // postponed to here.
7688                if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
7689                    String agent = mAppAgentMap.get(processName);
7690                    // Do not overwrite already requested agent.
7691                    if (profilerInfo == null) {
7692                        profilerInfo = new ProfilerInfo(null, null, 0, false, false,
7693                                mAppAgentMap.get(processName), true);
7694                    } else if (profilerInfo.agent == null) {
7695                        profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
7696                    }
7697                }
7698            }
7699
7700            if (profilerInfo != null && profilerInfo.profileFd != null) {
7701                profilerInfo.profileFd = profilerInfo.profileFd.dup();
7702                if (TextUtils.equals(mProfileApp, processName) && mProfilerInfo != null) {
7703                    clearProfilerLocked();
7704                }
7705            }
7706
7707            // We deprecated Build.SERIAL and it is not accessible to
7708            // apps that target the v2 security sandbox and to apps that
7709            // target APIs higher than O MR1. Since access to the serial
7710            // is now behind a permission we push down the value.
7711            final String buildSerial = (appInfo.targetSandboxVersion < 2
7712                    && appInfo.targetSdkVersion < Build.VERSION_CODES.P)
7713                            ? sTheRealBuildSerial : Build.UNKNOWN;
7714
7715            // Check if this is a secondary process that should be incorporated into some
7716            // currently active instrumentation.  (Note we do this AFTER all of the profiling
7717            // stuff above because profiling can currently happen only in the primary
7718            // instrumentation process.)
7719            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7720                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7721                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7722                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7723                        if (aInstr.mTargetProcesses.length == 0) {
7724                            // This is the wildcard mode, where every process brought up for
7725                            // the target instrumentation should be included.
7726                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7727                                app.instr = aInstr;
7728                                aInstr.mRunningProcesses.add(app);
7729                            }
7730                        } else {
7731                            for (String proc : aInstr.mTargetProcesses) {
7732                                if (proc.equals(app.processName)) {
7733                                    app.instr = aInstr;
7734                                    aInstr.mRunningProcesses.add(app);
7735                                    break;
7736                                }
7737                            }
7738                        }
7739                    }
7740                }
7741            }
7742
7743            // If we were asked to attach an agent on startup, do so now, before we're binding
7744            // application code.
7745            if (preBindAgent != null) {
7746                thread.attachAgent(preBindAgent);
7747            }
7748
7749
7750            // Figure out whether the app needs to run in autofill compat mode.
7751            boolean isAutofillCompatEnabled = false;
7752            if (UserHandle.getAppId(app.info.uid) >= Process.FIRST_APPLICATION_UID) {
7753                final AutofillManagerInternal afm = LocalServices.getService(
7754                        AutofillManagerInternal.class);
7755                if (afm != null) {
7756                    isAutofillCompatEnabled = afm.isCompatibilityModeRequested(
7757                            app.info.packageName, app.info.versionCode, app.userId);
7758                }
7759            }
7760
7761            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7762            mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
7763            if (app.isolatedEntryPoint != null) {
7764                // This is an isolated process which should just call an entry point instead of
7765                // being bound to an application.
7766                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7767            } else if (app.instr != null) {
7768                thread.bindApplication(processName, appInfo, providers,
7769                        app.instr.mClass,
7770                        profilerInfo, app.instr.mArguments,
7771                        app.instr.mWatcher,
7772                        app.instr.mUiAutomationConnection, testMode,
7773                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7774                        isRestrictedBackupMode || !normalMode, app.persistent,
7775                        new Configuration(getGlobalConfiguration()), app.compat,
7776                        getCommonServicesLocked(app.isolated),
7777                        mCoreSettingsObserver.getCoreSettingsLocked(),
7778                        buildSerial, isAutofillCompatEnabled);
7779            } else {
7780                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7781                        null, null, null, testMode,
7782                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7783                        isRestrictedBackupMode || !normalMode, app.persistent,
7784                        new Configuration(getGlobalConfiguration()), app.compat,
7785                        getCommonServicesLocked(app.isolated),
7786                        mCoreSettingsObserver.getCoreSettingsLocked(),
7787                        buildSerial, isAutofillCompatEnabled);
7788            }
7789            if (profilerInfo != null) {
7790                profilerInfo.closeFd();
7791                profilerInfo = null;
7792            }
7793            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7794            updateLruProcessLocked(app, false, null);
7795            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7796            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7797        } catch (Exception e) {
7798            // todo: Yikes!  What should we do?  For now we will try to
7799            // start another process, but that could easily get us in
7800            // an infinite loop of restarting processes...
7801            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7802
7803            app.resetPackageList(mProcessStats);
7804            app.unlinkDeathRecipient();
7805            startProcessLocked(app, "bind fail", processName);
7806            return false;
7807        }
7808
7809        // Remove this record from the list of starting applications.
7810        mPersistentStartingProcesses.remove(app);
7811        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7812                "Attach application locked removing on hold: " + app);
7813        mProcessesOnHold.remove(app);
7814
7815        boolean badApp = false;
7816        boolean didSomething = false;
7817
7818        // See if the top visible activity is waiting to run in this process...
7819        if (normalMode) {
7820            try {
7821                if (mStackSupervisor.attachApplicationLocked(app)) {
7822                    didSomething = true;
7823                }
7824            } catch (Exception e) {
7825                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7826                badApp = true;
7827            }
7828        }
7829
7830        // Find any services that should be running in this process...
7831        if (!badApp) {
7832            try {
7833                didSomething |= mServices.attachApplicationLocked(app, processName);
7834                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7835            } catch (Exception e) {
7836                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7837                badApp = true;
7838            }
7839        }
7840
7841        // Check if a next-broadcast receiver is in this process...
7842        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7843            try {
7844                didSomething |= sendPendingBroadcastsLocked(app);
7845                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7846            } catch (Exception e) {
7847                // If the app died trying to launch the receiver we declare it 'bad'
7848                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7849                badApp = true;
7850            }
7851        }
7852
7853        // Check whether the next backup agent is in this process...
7854        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7855            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7856                    "New app is backup target, launching agent for " + app);
7857            notifyPackageUse(mBackupTarget.appInfo.packageName,
7858                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7859            try {
7860                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7861                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7862                        mBackupTarget.backupMode);
7863            } catch (Exception e) {
7864                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7865                badApp = true;
7866            }
7867        }
7868
7869        if (badApp) {
7870            app.kill("error during init", true);
7871            handleAppDiedLocked(app, false, true);
7872            return false;
7873        }
7874
7875        if (!didSomething) {
7876            updateOomAdjLocked();
7877            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7878        }
7879
7880        return true;
7881    }
7882
7883    @Override
7884    public final void attachApplication(IApplicationThread thread, long startSeq) {
7885        synchronized (this) {
7886            int callingPid = Binder.getCallingPid();
7887            final int callingUid = Binder.getCallingUid();
7888            final long origId = Binder.clearCallingIdentity();
7889            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
7890            Binder.restoreCallingIdentity(origId);
7891        }
7892    }
7893
7894    @Override
7895    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7896        final long origId = Binder.clearCallingIdentity();
7897        synchronized (this) {
7898            ActivityStack stack = ActivityRecord.getStackLocked(token);
7899            if (stack != null) {
7900                ActivityRecord r =
7901                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7902                                false /* processPausingActivities */, config);
7903                if (stopProfiling) {
7904                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
7905                        clearProfilerLocked();
7906                    }
7907                }
7908            }
7909        }
7910        Binder.restoreCallingIdentity(origId);
7911    }
7912
7913    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7914        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7915                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7916    }
7917
7918    void enableScreenAfterBoot() {
7919        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7920                SystemClock.uptimeMillis());
7921        mWindowManager.enableScreenAfterBoot();
7922
7923        synchronized (this) {
7924            updateEventDispatchingLocked();
7925        }
7926    }
7927
7928    @Override
7929    public void showBootMessage(final CharSequence msg, final boolean always) {
7930        if (Binder.getCallingUid() != myUid()) {
7931            throw new SecurityException();
7932        }
7933        mWindowManager.showBootMessage(msg, always);
7934    }
7935
7936    @Override
7937    public void keyguardGoingAway(int flags) {
7938        enforceNotIsolatedCaller("keyguardGoingAway");
7939        final long token = Binder.clearCallingIdentity();
7940        try {
7941            synchronized (this) {
7942                mKeyguardController.keyguardGoingAway(flags);
7943            }
7944        } finally {
7945            Binder.restoreCallingIdentity(token);
7946        }
7947    }
7948
7949    /**
7950     * @return whther the keyguard is currently locked.
7951     */
7952    boolean isKeyguardLocked() {
7953        return mKeyguardController.isKeyguardLocked();
7954    }
7955
7956    final void finishBooting() {
7957        synchronized (this) {
7958            if (!mBootAnimationComplete) {
7959                mCallFinishBooting = true;
7960                return;
7961            }
7962            mCallFinishBooting = false;
7963        }
7964
7965        ArraySet<String> completedIsas = new ArraySet<String>();
7966        for (String abi : Build.SUPPORTED_ABIS) {
7967            zygoteProcess.establishZygoteConnectionForAbi(abi);
7968            final String instructionSet = VMRuntime.getInstructionSet(abi);
7969            if (!completedIsas.contains(instructionSet)) {
7970                try {
7971                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7972                } catch (InstallerException e) {
7973                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7974                            e.getMessage() +")");
7975                }
7976                completedIsas.add(instructionSet);
7977            }
7978        }
7979
7980        IntentFilter pkgFilter = new IntentFilter();
7981        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7982        pkgFilter.addDataScheme("package");
7983        mContext.registerReceiver(new BroadcastReceiver() {
7984            @Override
7985            public void onReceive(Context context, Intent intent) {
7986                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7987                if (pkgs != null) {
7988                    for (String pkg : pkgs) {
7989                        synchronized (ActivityManagerService.this) {
7990                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7991                                    0, "query restart")) {
7992                                setResultCode(Activity.RESULT_OK);
7993                                return;
7994                            }
7995                        }
7996                    }
7997                }
7998            }
7999        }, pkgFilter);
8000
8001        IntentFilter dumpheapFilter = new IntentFilter();
8002        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
8003        mContext.registerReceiver(new BroadcastReceiver() {
8004            @Override
8005            public void onReceive(Context context, Intent intent) {
8006                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
8007                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
8008                } else {
8009                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
8010                }
8011            }
8012        }, dumpheapFilter);
8013
8014        // Let system services know.
8015        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
8016
8017        synchronized (this) {
8018            // Ensure that any processes we had put on hold are now started
8019            // up.
8020            final int NP = mProcessesOnHold.size();
8021            if (NP > 0) {
8022                ArrayList<ProcessRecord> procs =
8023                    new ArrayList<ProcessRecord>(mProcessesOnHold);
8024                for (int ip=0; ip<NP; ip++) {
8025                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
8026                            + procs.get(ip));
8027                    startProcessLocked(procs.get(ip), "on-hold", null);
8028                }
8029            }
8030            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
8031                return;
8032            }
8033            // Start looking for apps that are abusing wake locks.
8034            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
8035            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
8036            // Tell anyone interested that we are done booting!
8037            SystemProperties.set("sys.boot_completed", "1");
8038
8039            // And trigger dev.bootcomplete if we are not showing encryption progress
8040            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
8041                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
8042                SystemProperties.set("dev.bootcomplete", "1");
8043            }
8044            mUserController.sendBootCompleted(
8045                    new IIntentReceiver.Stub() {
8046                        @Override
8047                        public void performReceive(Intent intent, int resultCode,
8048                                String data, Bundle extras, boolean ordered,
8049                                boolean sticky, int sendingUser) {
8050                            synchronized (ActivityManagerService.this) {
8051                                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
8052                            }
8053                        }
8054                    });
8055            mUserController.scheduleStartProfiles();
8056        }
8057    }
8058
8059    @Override
8060    public void bootAnimationComplete() {
8061        final boolean callFinishBooting;
8062        synchronized (this) {
8063            callFinishBooting = mCallFinishBooting;
8064            mBootAnimationComplete = true;
8065        }
8066        if (callFinishBooting) {
8067            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
8068            finishBooting();
8069            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
8070        }
8071    }
8072
8073    final void ensureBootCompleted() {
8074        boolean booting;
8075        boolean enableScreen;
8076        synchronized (this) {
8077            booting = mBooting;
8078            mBooting = false;
8079            enableScreen = !mBooted;
8080            mBooted = true;
8081        }
8082
8083        if (booting) {
8084            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
8085            finishBooting();
8086            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
8087        }
8088
8089        if (enableScreen) {
8090            enableScreenAfterBoot();
8091        }
8092    }
8093
8094    @Override
8095    public final void activityResumed(IBinder token) {
8096        final long origId = Binder.clearCallingIdentity();
8097        synchronized(this) {
8098            ActivityRecord.activityResumedLocked(token);
8099            mWindowManager.notifyAppResumedFinished(token);
8100        }
8101        Binder.restoreCallingIdentity(origId);
8102    }
8103
8104    @Override
8105    public final void activityPaused(IBinder token) {
8106        final long origId = Binder.clearCallingIdentity();
8107        synchronized(this) {
8108            ActivityStack stack = ActivityRecord.getStackLocked(token);
8109            if (stack != null) {
8110                stack.activityPausedLocked(token, false);
8111            }
8112        }
8113        Binder.restoreCallingIdentity(origId);
8114    }
8115
8116    @Override
8117    public final void activityStopped(IBinder token, Bundle icicle,
8118            PersistableBundle persistentState, CharSequence description) {
8119        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
8120
8121        // Refuse possible leaked file descriptors
8122        if (icicle != null && icicle.hasFileDescriptors()) {
8123            throw new IllegalArgumentException("File descriptors passed in Bundle");
8124        }
8125
8126        final long origId = Binder.clearCallingIdentity();
8127
8128        synchronized (this) {
8129            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8130            if (r != null) {
8131                r.activityStoppedLocked(icicle, persistentState, description);
8132            }
8133        }
8134
8135        trimApplications();
8136
8137        Binder.restoreCallingIdentity(origId);
8138    }
8139
8140    @Override
8141    public final void activityDestroyed(IBinder token) {
8142        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
8143        synchronized (this) {
8144            ActivityStack stack = ActivityRecord.getStackLocked(token);
8145            if (stack != null) {
8146                stack.activityDestroyedLocked(token, "activityDestroyed");
8147            }
8148        }
8149    }
8150
8151    @Override
8152    public final void activityRelaunched(IBinder token) {
8153        final long origId = Binder.clearCallingIdentity();
8154        synchronized (this) {
8155            mStackSupervisor.activityRelaunchedLocked(token);
8156        }
8157        Binder.restoreCallingIdentity(origId);
8158    }
8159
8160    @Override
8161    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
8162            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
8163        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
8164                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
8165        synchronized (this) {
8166            ActivityRecord record = ActivityRecord.isInStackLocked(token);
8167            if (record == null) {
8168                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
8169                        + "found for: " + token);
8170            }
8171            record.setSizeConfigurations(horizontalSizeConfiguration,
8172                    verticalSizeConfigurations, smallestSizeConfigurations);
8173        }
8174    }
8175
8176    @Override
8177    public final void notifyLaunchTaskBehindComplete(IBinder token) {
8178        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
8179    }
8180
8181    @Override
8182    public final void notifyEnterAnimationComplete(IBinder token) {
8183        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
8184    }
8185
8186    @Override
8187    public String getCallingPackage(IBinder token) {
8188        synchronized (this) {
8189            ActivityRecord r = getCallingRecordLocked(token);
8190            return r != null ? r.info.packageName : null;
8191        }
8192    }
8193
8194    @Override
8195    public ComponentName getCallingActivity(IBinder token) {
8196        synchronized (this) {
8197            ActivityRecord r = getCallingRecordLocked(token);
8198            return r != null ? r.intent.getComponent() : null;
8199        }
8200    }
8201
8202    private ActivityRecord getCallingRecordLocked(IBinder token) {
8203        ActivityRecord r = ActivityRecord.isInStackLocked(token);
8204        if (r == null) {
8205            return null;
8206        }
8207        return r.resultTo;
8208    }
8209
8210    @Override
8211    public ComponentName getActivityClassForToken(IBinder token) {
8212        synchronized(this) {
8213            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8214            if (r == null) {
8215                return null;
8216            }
8217            return r.intent.getComponent();
8218        }
8219    }
8220
8221    @Override
8222    public String getPackageForToken(IBinder token) {
8223        synchronized(this) {
8224            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8225            if (r == null) {
8226                return null;
8227            }
8228            return r.packageName;
8229        }
8230    }
8231
8232    @Override
8233    public boolean isRootVoiceInteraction(IBinder token) {
8234        synchronized(this) {
8235            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8236            if (r == null) {
8237                return false;
8238            }
8239            return r.rootVoiceInteraction;
8240        }
8241    }
8242
8243    @Override
8244    public IIntentSender getIntentSender(int type,
8245            String packageName, IBinder token, String resultWho,
8246            int requestCode, Intent[] intents, String[] resolvedTypes,
8247            int flags, Bundle bOptions, int userId) {
8248        enforceNotIsolatedCaller("getIntentSender");
8249        // Refuse possible leaked file descriptors
8250        if (intents != null) {
8251            if (intents.length < 1) {
8252                throw new IllegalArgumentException("Intents array length must be >= 1");
8253            }
8254            for (int i=0; i<intents.length; i++) {
8255                Intent intent = intents[i];
8256                if (intent != null) {
8257                    if (intent.hasFileDescriptors()) {
8258                        throw new IllegalArgumentException("File descriptors passed in Intent");
8259                    }
8260                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
8261                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
8262                        throw new IllegalArgumentException(
8263                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
8264                    }
8265                    intents[i] = new Intent(intent);
8266                }
8267            }
8268            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
8269                throw new IllegalArgumentException(
8270                        "Intent array length does not match resolvedTypes length");
8271            }
8272        }
8273        if (bOptions != null) {
8274            if (bOptions.hasFileDescriptors()) {
8275                throw new IllegalArgumentException("File descriptors passed in options");
8276            }
8277        }
8278
8279        synchronized(this) {
8280            int callingUid = Binder.getCallingUid();
8281            int origUserId = userId;
8282            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8283                    type == ActivityManager.INTENT_SENDER_BROADCAST,
8284                    ALLOW_NON_FULL, "getIntentSender", null);
8285            if (origUserId == UserHandle.USER_CURRENT) {
8286                // We don't want to evaluate this until the pending intent is
8287                // actually executed.  However, we do want to always do the
8288                // security checking for it above.
8289                userId = UserHandle.USER_CURRENT;
8290            }
8291            try {
8292                if (callingUid != 0 && callingUid != SYSTEM_UID) {
8293                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
8294                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
8295                    if (!UserHandle.isSameApp(callingUid, uid)) {
8296                        String msg = "Permission Denial: getIntentSender() from pid="
8297                            + Binder.getCallingPid()
8298                            + ", uid=" + Binder.getCallingUid()
8299                            + ", (need uid=" + uid + ")"
8300                            + " is not allowed to send as package " + packageName;
8301                        Slog.w(TAG, msg);
8302                        throw new SecurityException(msg);
8303                    }
8304                }
8305
8306                return getIntentSenderLocked(type, packageName, callingUid, userId,
8307                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
8308
8309            } catch (RemoteException e) {
8310                throw new SecurityException(e);
8311            }
8312        }
8313    }
8314
8315    IIntentSender getIntentSenderLocked(int type, String packageName,
8316            int callingUid, int userId, IBinder token, String resultWho,
8317            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
8318            Bundle bOptions) {
8319        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
8320        ActivityRecord activity = null;
8321        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8322            activity = ActivityRecord.isInStackLocked(token);
8323            if (activity == null) {
8324                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
8325                return null;
8326            }
8327            if (activity.finishing) {
8328                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
8329                return null;
8330            }
8331        }
8332
8333        // We're going to be splicing together extras before sending, so we're
8334        // okay poking into any contained extras.
8335        if (intents != null) {
8336            for (int i = 0; i < intents.length; i++) {
8337                intents[i].setDefusable(true);
8338            }
8339        }
8340        Bundle.setDefusable(bOptions, true);
8341
8342        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
8343        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
8344        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
8345        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
8346                |PendingIntent.FLAG_UPDATE_CURRENT);
8347
8348        PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity,
8349                resultWho, requestCode, intents, resolvedTypes, flags,
8350                SafeActivityOptions.fromBundle(bOptions), userId);
8351        WeakReference<PendingIntentRecord> ref;
8352        ref = mIntentSenderRecords.get(key);
8353        PendingIntentRecord rec = ref != null ? ref.get() : null;
8354        if (rec != null) {
8355            if (!cancelCurrent) {
8356                if (updateCurrent) {
8357                    if (rec.key.requestIntent != null) {
8358                        rec.key.requestIntent.replaceExtras(intents != null ?
8359                                intents[intents.length - 1] : null);
8360                    }
8361                    if (intents != null) {
8362                        intents[intents.length-1] = rec.key.requestIntent;
8363                        rec.key.allIntents = intents;
8364                        rec.key.allResolvedTypes = resolvedTypes;
8365                    } else {
8366                        rec.key.allIntents = null;
8367                        rec.key.allResolvedTypes = null;
8368                    }
8369                }
8370                return rec;
8371            }
8372            makeIntentSenderCanceledLocked(rec);
8373            mIntentSenderRecords.remove(key);
8374        }
8375        if (noCreate) {
8376            return rec;
8377        }
8378        rec = new PendingIntentRecord(this, key, callingUid);
8379        mIntentSenderRecords.put(key, rec.ref);
8380        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8381            if (activity.pendingResults == null) {
8382                activity.pendingResults
8383                        = new HashSet<WeakReference<PendingIntentRecord>>();
8384            }
8385            activity.pendingResults.add(rec.ref);
8386        }
8387        return rec;
8388    }
8389
8390    @Override
8391    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
8392            Intent intent, String resolvedType,
8393            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
8394        if (target instanceof PendingIntentRecord) {
8395            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
8396                    whitelistToken, finishedReceiver, requiredPermission, options);
8397        } else {
8398            if (intent == null) {
8399                // Weird case: someone has given us their own custom IIntentSender, and now
8400                // they have someone else trying to send to it but of course this isn't
8401                // really a PendingIntent, so there is no base Intent, and the caller isn't
8402                // supplying an Intent... but we never want to dispatch a null Intent to
8403                // a receiver, so um...  let's make something up.
8404                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
8405                intent = new Intent(Intent.ACTION_MAIN);
8406            }
8407            try {
8408                target.send(code, intent, resolvedType, whitelistToken, null,
8409                        requiredPermission, options);
8410            } catch (RemoteException e) {
8411            }
8412            // Platform code can rely on getting a result back when the send is done, but if
8413            // this intent sender is from outside of the system we can't rely on it doing that.
8414            // So instead we don't give it the result receiver, and instead just directly
8415            // report the finish immediately.
8416            if (finishedReceiver != null) {
8417                try {
8418                    finishedReceiver.performReceive(intent, 0,
8419                            null, null, false, false, UserHandle.getCallingUserId());
8420                } catch (RemoteException e) {
8421                }
8422            }
8423            return 0;
8424        }
8425    }
8426
8427    @Override
8428    public void cancelIntentSender(IIntentSender sender) {
8429        if (!(sender instanceof PendingIntentRecord)) {
8430            return;
8431        }
8432        synchronized(this) {
8433            PendingIntentRecord rec = (PendingIntentRecord)sender;
8434            try {
8435                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
8436                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
8437                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
8438                    String msg = "Permission Denial: cancelIntentSender() from pid="
8439                        + Binder.getCallingPid()
8440                        + ", uid=" + Binder.getCallingUid()
8441                        + " is not allowed to cancel package "
8442                        + rec.key.packageName;
8443                    Slog.w(TAG, msg);
8444                    throw new SecurityException(msg);
8445                }
8446            } catch (RemoteException e) {
8447                throw new SecurityException(e);
8448            }
8449            cancelIntentSenderLocked(rec, true);
8450        }
8451    }
8452
8453    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
8454        makeIntentSenderCanceledLocked(rec);
8455        mIntentSenderRecords.remove(rec.key);
8456        if (cleanActivity && rec.key.activity != null) {
8457            rec.key.activity.pendingResults.remove(rec.ref);
8458        }
8459    }
8460
8461    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
8462        rec.canceled = true;
8463        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
8464        if (callbacks != null) {
8465            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
8466        }
8467    }
8468
8469    @Override
8470    public String getPackageForIntentSender(IIntentSender pendingResult) {
8471        if (!(pendingResult instanceof PendingIntentRecord)) {
8472            return null;
8473        }
8474        try {
8475            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8476            return res.key.packageName;
8477        } catch (ClassCastException e) {
8478        }
8479        return null;
8480    }
8481
8482    @Override
8483    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
8484        if (!(sender instanceof PendingIntentRecord)) {
8485            return;
8486        }
8487        synchronized(this) {
8488            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
8489        }
8490    }
8491
8492    @Override
8493    public void unregisterIntentSenderCancelListener(IIntentSender sender,
8494            IResultReceiver receiver) {
8495        if (!(sender instanceof PendingIntentRecord)) {
8496            return;
8497        }
8498        synchronized(this) {
8499            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
8500        }
8501    }
8502
8503    @Override
8504    public int getUidForIntentSender(IIntentSender sender) {
8505        if (sender instanceof PendingIntentRecord) {
8506            try {
8507                PendingIntentRecord res = (PendingIntentRecord)sender;
8508                return res.uid;
8509            } catch (ClassCastException e) {
8510            }
8511        }
8512        return -1;
8513    }
8514
8515    @Override
8516    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
8517        if (!(pendingResult instanceof PendingIntentRecord)) {
8518            return false;
8519        }
8520        try {
8521            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8522            if (res.key.allIntents == null) {
8523                return false;
8524            }
8525            for (int i=0; i<res.key.allIntents.length; i++) {
8526                Intent intent = res.key.allIntents[i];
8527                if (intent.getPackage() != null && intent.getComponent() != null) {
8528                    return false;
8529                }
8530            }
8531            return true;
8532        } catch (ClassCastException e) {
8533        }
8534        return false;
8535    }
8536
8537    @Override
8538    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
8539        if (!(pendingResult instanceof PendingIntentRecord)) {
8540            return false;
8541        }
8542        try {
8543            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8544            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
8545                return true;
8546            }
8547            return false;
8548        } catch (ClassCastException e) {
8549        }
8550        return false;
8551    }
8552
8553    @Override
8554    public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
8555        if (pendingResult instanceof PendingIntentRecord) {
8556            final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
8557            return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
8558        }
8559        return false;
8560    }
8561
8562    @Override
8563    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
8564        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
8565                "getIntentForIntentSender()");
8566        if (!(pendingResult instanceof PendingIntentRecord)) {
8567            return null;
8568        }
8569        try {
8570            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8571            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
8572        } catch (ClassCastException e) {
8573        }
8574        return null;
8575    }
8576
8577    @Override
8578    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
8579        if (!(pendingResult instanceof PendingIntentRecord)) {
8580            return null;
8581        }
8582        try {
8583            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8584            synchronized (this) {
8585                return getTagForIntentSenderLocked(res, prefix);
8586            }
8587        } catch (ClassCastException e) {
8588        }
8589        return null;
8590    }
8591
8592    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
8593        final Intent intent = res.key.requestIntent;
8594        if (intent != null) {
8595            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
8596                    || res.lastTagPrefix.equals(prefix))) {
8597                return res.lastTag;
8598            }
8599            res.lastTagPrefix = prefix;
8600            final StringBuilder sb = new StringBuilder(128);
8601            if (prefix != null) {
8602                sb.append(prefix);
8603            }
8604            if (intent.getAction() != null) {
8605                sb.append(intent.getAction());
8606            } else if (intent.getComponent() != null) {
8607                intent.getComponent().appendShortString(sb);
8608            } else {
8609                sb.append("?");
8610            }
8611            return res.lastTag = sb.toString();
8612        }
8613        return null;
8614    }
8615
8616    @Override
8617    public void setProcessLimit(int max) {
8618        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8619                "setProcessLimit()");
8620        synchronized (this) {
8621            mConstants.setOverrideMaxCachedProcesses(max);
8622        }
8623        trimApplications();
8624    }
8625
8626    @Override
8627    public int getProcessLimit() {
8628        synchronized (this) {
8629            return mConstants.getOverrideMaxCachedProcesses();
8630        }
8631    }
8632
8633    void importanceTokenDied(ImportanceToken token) {
8634        synchronized (ActivityManagerService.this) {
8635            synchronized (mPidsSelfLocked) {
8636                ImportanceToken cur
8637                    = mImportantProcesses.get(token.pid);
8638                if (cur != token) {
8639                    return;
8640                }
8641                mImportantProcesses.remove(token.pid);
8642                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
8643                if (pr == null) {
8644                    return;
8645                }
8646                pr.forcingToImportant = null;
8647                updateProcessForegroundLocked(pr, false, false);
8648            }
8649            updateOomAdjLocked();
8650        }
8651    }
8652
8653    @Override
8654    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8655        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8656                "setProcessImportant()");
8657        synchronized(this) {
8658            boolean changed = false;
8659
8660            synchronized (mPidsSelfLocked) {
8661                ProcessRecord pr = mPidsSelfLocked.get(pid);
8662                if (pr == null && isForeground) {
8663                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8664                    return;
8665                }
8666                ImportanceToken oldToken = mImportantProcesses.get(pid);
8667                if (oldToken != null) {
8668                    oldToken.token.unlinkToDeath(oldToken, 0);
8669                    mImportantProcesses.remove(pid);
8670                    if (pr != null) {
8671                        pr.forcingToImportant = null;
8672                    }
8673                    changed = true;
8674                }
8675                if (isForeground && token != null) {
8676                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8677                        @Override
8678                        public void binderDied() {
8679                            importanceTokenDied(this);
8680                        }
8681                    };
8682                    try {
8683                        token.linkToDeath(newToken, 0);
8684                        mImportantProcesses.put(pid, newToken);
8685                        pr.forcingToImportant = newToken;
8686                        changed = true;
8687                    } catch (RemoteException e) {
8688                        // If the process died while doing this, we will later
8689                        // do the cleanup with the process death link.
8690                    }
8691                }
8692            }
8693
8694            if (changed) {
8695                updateOomAdjLocked();
8696            }
8697        }
8698    }
8699
8700    @Override
8701    public boolean isAppForeground(int uid) {
8702        synchronized (this) {
8703            UidRecord uidRec = mActiveUids.get(uid);
8704            if (uidRec == null || uidRec.idle) {
8705                return false;
8706            }
8707            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8708        }
8709    }
8710
8711    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8712    // be guarded by permission checking.
8713    int getUidState(int uid) {
8714        synchronized (this) {
8715            return getUidStateLocked(uid);
8716        }
8717    }
8718
8719    int getUidStateLocked(int uid) {
8720        UidRecord uidRec = mActiveUids.get(uid);
8721        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8722    }
8723
8724    @Override
8725    public boolean isInMultiWindowMode(IBinder token) {
8726        final long origId = Binder.clearCallingIdentity();
8727        try {
8728            synchronized(this) {
8729                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8730                if (r == null) {
8731                    return false;
8732                }
8733                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8734                return r.inMultiWindowMode();
8735            }
8736        } finally {
8737            Binder.restoreCallingIdentity(origId);
8738        }
8739    }
8740
8741    @Override
8742    public boolean isInPictureInPictureMode(IBinder token) {
8743        final long origId = Binder.clearCallingIdentity();
8744        try {
8745            synchronized(this) {
8746                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8747            }
8748        } finally {
8749            Binder.restoreCallingIdentity(origId);
8750        }
8751    }
8752
8753    private boolean isInPictureInPictureMode(ActivityRecord r) {
8754        if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8755                || r.getStack().isInStackLocked(r) == null) {
8756            return false;
8757        }
8758
8759        // If we are animating to fullscreen then we have already dispatched the PIP mode
8760        // changed, so we should reflect that check here as well.
8761        final PinnedActivityStack stack = r.getStack();
8762        final PinnedStackWindowController windowController = stack.getWindowContainerController();
8763        return !windowController.isAnimatingBoundsToFullscreen();
8764    }
8765
8766    @Override
8767    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8768        final long origId = Binder.clearCallingIdentity();
8769        try {
8770            synchronized(this) {
8771                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8772                        "enterPictureInPictureMode", token, params);
8773
8774                // If the activity is already in picture in picture mode, then just return early
8775                if (isInPictureInPictureMode(r)) {
8776                    return true;
8777                }
8778
8779                // Activity supports picture-in-picture, now check that we can enter PiP at this
8780                // point, if it is
8781                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8782                        false /* beforeStopping */)) {
8783                    return false;
8784                }
8785
8786                final Runnable enterPipRunnable = () -> {
8787                    // Only update the saved args from the args that are set
8788                    r.pictureInPictureArgs.copyOnlySet(params);
8789                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8790                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8791                    // Adjust the source bounds by the insets for the transition down
8792                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8793                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8794                            "enterPictureInPictureMode");
8795                    final PinnedActivityStack stack = r.getStack();
8796                    stack.setPictureInPictureAspectRatio(aspectRatio);
8797                    stack.setPictureInPictureActions(actions);
8798                    MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
8799                            r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
8800                    logPictureInPictureArgs(params);
8801                };
8802
8803                if (isKeyguardLocked()) {
8804                    // If the keyguard is showing or occluded, then try and dismiss it before
8805                    // entering picture-in-picture (this will prompt the user to authenticate if the
8806                    // device is currently locked).
8807                    try {
8808                        dismissKeyguard(token, new KeyguardDismissCallback() {
8809                            @Override
8810                            public void onDismissSucceeded() throws RemoteException {
8811                                mHandler.post(enterPipRunnable);
8812                            }
8813                        }, null /* message */);
8814                    } catch (RemoteException e) {
8815                        // Local call
8816                    }
8817                } else {
8818                    // Enter picture in picture immediately otherwise
8819                    enterPipRunnable.run();
8820                }
8821                return true;
8822            }
8823        } finally {
8824            Binder.restoreCallingIdentity(origId);
8825        }
8826    }
8827
8828    @Override
8829    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8830        final long origId = Binder.clearCallingIdentity();
8831        try {
8832            synchronized(this) {
8833                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8834                        "setPictureInPictureParams", token, params);
8835
8836                // Only update the saved args from the args that are set
8837                r.pictureInPictureArgs.copyOnlySet(params);
8838                if (r.inPinnedWindowingMode()) {
8839                    // If the activity is already in picture-in-picture, update the pinned stack now
8840                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8841                    // be used the next time the activity enters PiP
8842                    final PinnedActivityStack stack = r.getStack();
8843                    if (!stack.isAnimatingBoundsToFullscreen()) {
8844                        stack.setPictureInPictureAspectRatio(
8845                                r.pictureInPictureArgs.getAspectRatio());
8846                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8847                    }
8848                }
8849                logPictureInPictureArgs(params);
8850            }
8851        } finally {
8852            Binder.restoreCallingIdentity(origId);
8853        }
8854    }
8855
8856    @Override
8857    public int getMaxNumPictureInPictureActions(IBinder token) {
8858        // Currently, this is a static constant, but later, we may change this to be dependent on
8859        // the context of the activity
8860        return 3;
8861    }
8862
8863    private void logPictureInPictureArgs(PictureInPictureParams params) {
8864        if (params.hasSetActions()) {
8865            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8866                    params.getActions().size());
8867        }
8868        if (params.hasSetAspectRatio()) {
8869            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8870            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8871            MetricsLogger.action(lm);
8872        }
8873    }
8874
8875    /**
8876     * Checks the state of the system and the activity associated with the given {@param token} to
8877     * verify that picture-in-picture is supported for that activity.
8878     *
8879     * @return the activity record for the given {@param token} if all the checks pass.
8880     */
8881    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8882            IBinder token, PictureInPictureParams params) {
8883        if (!mSupportsPictureInPicture) {
8884            throw new IllegalStateException(caller
8885                    + ": Device doesn't support picture-in-picture mode.");
8886        }
8887
8888        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8889        if (r == null) {
8890            throw new IllegalStateException(caller
8891                    + ": Can't find activity for token=" + token);
8892        }
8893
8894        if (!r.supportsPictureInPicture()) {
8895            throw new IllegalStateException(caller
8896                    + ": Current activity does not support picture-in-picture.");
8897        }
8898
8899        if (params.hasSetAspectRatio()
8900                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8901                        params.getAspectRatio())) {
8902            final float minAspectRatio = mContext.getResources().getFloat(
8903                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8904            final float maxAspectRatio = mContext.getResources().getFloat(
8905                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8906            throw new IllegalArgumentException(String.format(caller
8907                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8908                            minAspectRatio, maxAspectRatio));
8909        }
8910
8911        // Truncate the number of actions if necessary
8912        params.truncateActions(getMaxNumPictureInPictureActions(token));
8913
8914        return r;
8915    }
8916
8917    // =========================================================
8918    // PROCESS INFO
8919    // =========================================================
8920
8921    static class ProcessInfoService extends IProcessInfoService.Stub {
8922        final ActivityManagerService mActivityManagerService;
8923        ProcessInfoService(ActivityManagerService activityManagerService) {
8924            mActivityManagerService = activityManagerService;
8925        }
8926
8927        @Override
8928        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8929            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8930                    /*in*/ pids, /*out*/ states, null);
8931        }
8932
8933        @Override
8934        public void getProcessStatesAndOomScoresFromPids(
8935                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8936            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8937                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8938        }
8939    }
8940
8941    /**
8942     * For each PID in the given input array, write the current process state
8943     * for that process into the states array, or -1 to indicate that no
8944     * process with the given PID exists. If scores array is provided, write
8945     * the oom score for the process into the scores array, with INVALID_ADJ
8946     * indicating the PID doesn't exist.
8947     */
8948    public void getProcessStatesAndOomScoresForPIDs(
8949            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8950        if (scores != null) {
8951            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8952                    "getProcessStatesAndOomScoresForPIDs()");
8953        }
8954
8955        if (pids == null) {
8956            throw new NullPointerException("pids");
8957        } else if (states == null) {
8958            throw new NullPointerException("states");
8959        } else if (pids.length != states.length) {
8960            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8961        } else if (scores != null && pids.length != scores.length) {
8962            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8963        }
8964
8965        synchronized (mPidsSelfLocked) {
8966            for (int i = 0; i < pids.length; i++) {
8967                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8968                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8969                        pr.curProcState;
8970                if (scores != null) {
8971                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8972                }
8973            }
8974        }
8975    }
8976
8977    // =========================================================
8978    // PERMISSIONS
8979    // =========================================================
8980
8981    static class PermissionController extends IPermissionController.Stub {
8982        ActivityManagerService mActivityManagerService;
8983        PermissionController(ActivityManagerService activityManagerService) {
8984            mActivityManagerService = activityManagerService;
8985        }
8986
8987        @Override
8988        public boolean checkPermission(String permission, int pid, int uid) {
8989            return mActivityManagerService.checkPermission(permission, pid,
8990                    uid) == PackageManager.PERMISSION_GRANTED;
8991        }
8992
8993        @Override
8994        public int noteOp(String op, int uid, String packageName) {
8995            return mActivityManagerService.mAppOpsService
8996                    .noteOperation(AppOpsManager.strOpToOp(op), uid, packageName);
8997        }
8998
8999        @Override
9000        public String[] getPackagesForUid(int uid) {
9001            return mActivityManagerService.mContext.getPackageManager()
9002                    .getPackagesForUid(uid);
9003        }
9004
9005        @Override
9006        public boolean isRuntimePermission(String permission) {
9007            try {
9008                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
9009                        .getPermissionInfo(permission, 0);
9010                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
9011                        == PermissionInfo.PROTECTION_DANGEROUS;
9012            } catch (NameNotFoundException nnfe) {
9013                Slog.e(TAG, "No such permission: "+ permission, nnfe);
9014            }
9015            return false;
9016        }
9017
9018        @Override
9019        public int getPackageUid(String packageName, int flags) {
9020            try {
9021                return mActivityManagerService.mContext.getPackageManager()
9022                        .getPackageUid(packageName, flags);
9023            } catch (NameNotFoundException nnfe) {
9024                return -1;
9025            }
9026        }
9027    }
9028
9029    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
9030        @Override
9031        public int checkComponentPermission(String permission, int pid, int uid,
9032                int owningUid, boolean exported) {
9033            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
9034                    owningUid, exported);
9035        }
9036
9037        @Override
9038        public Object getAMSLock() {
9039            return ActivityManagerService.this;
9040        }
9041    }
9042
9043    int checkComponentPermission(String permission, int pid, int uid,
9044            int owningUid, boolean exported) {
9045        if (pid == MY_PID) {
9046            return PackageManager.PERMISSION_GRANTED;
9047        }
9048        return ActivityManager.checkComponentPermission(permission, uid,
9049                owningUid, exported);
9050    }
9051
9052    /**
9053     * As the only public entry point for permissions checking, this method
9054     * can enforce the semantic that requesting a check on a null global
9055     * permission is automatically denied.  (Internally a null permission
9056     * string is used when calling {@link #checkComponentPermission} in cases
9057     * when only uid-based security is needed.)
9058     *
9059     * This can be called with or without the global lock held.
9060     */
9061    @Override
9062    public int checkPermission(String permission, int pid, int uid) {
9063        if (permission == null) {
9064            return PackageManager.PERMISSION_DENIED;
9065        }
9066        return checkComponentPermission(permission, pid, uid, -1, true);
9067    }
9068
9069    @Override
9070    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
9071        if (permission == null) {
9072            return PackageManager.PERMISSION_DENIED;
9073        }
9074
9075        // We might be performing an operation on behalf of an indirect binder
9076        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
9077        // client identity accordingly before proceeding.
9078        Identity tlsIdentity = sCallerIdentity.get();
9079        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9080            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
9081                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
9082            uid = tlsIdentity.uid;
9083            pid = tlsIdentity.pid;
9084        }
9085
9086        return checkComponentPermission(permission, pid, uid, -1, true);
9087    }
9088
9089    /**
9090     * Binder IPC calls go through the public entry point.
9091     * This can be called with or without the global lock held.
9092     */
9093    int checkCallingPermission(String permission) {
9094        return checkPermission(permission,
9095                Binder.getCallingPid(),
9096                UserHandle.getAppId(Binder.getCallingUid()));
9097    }
9098
9099    /**
9100     * This can be called with or without the global lock held.
9101     */
9102    void enforceCallingPermission(String permission, String func) {
9103        if (checkCallingPermission(permission)
9104                == PackageManager.PERMISSION_GRANTED) {
9105            return;
9106        }
9107
9108        String msg = "Permission Denial: " + func + " from pid="
9109                + Binder.getCallingPid()
9110                + ", uid=" + Binder.getCallingUid()
9111                + " requires " + permission;
9112        Slog.w(TAG, msg);
9113        throw new SecurityException(msg);
9114    }
9115
9116    /**
9117     * This can be called with or without the global lock held.
9118     */
9119    void enforcePermission(String permission, int pid, int uid, String func) {
9120        if (checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED) {
9121            return;
9122        }
9123
9124        String msg = "Permission Denial: " + func + " from pid=" + pid + ", uid=" + uid
9125                + " requires " + permission;
9126        Slog.w(TAG, msg);
9127        throw new SecurityException(msg);
9128    }
9129
9130    /**
9131     * This can be called with or without the global lock held.
9132     */
9133    void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
9134        if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
9135            enforceCallingPermission(permission, func);
9136        }
9137    }
9138
9139    /**
9140     * Determine if UID is holding permissions required to access {@link Uri} in
9141     * the given {@link ProviderInfo}. Final permission checking is always done
9142     * in {@link ContentProvider}.
9143     */
9144    private final boolean checkHoldingPermissionsLocked(
9145            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
9146        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9147                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
9148        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
9149            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
9150                    != PERMISSION_GRANTED) {
9151                return false;
9152            }
9153        }
9154        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
9155    }
9156
9157    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
9158            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
9159        if (pi.applicationInfo.uid == uid) {
9160            return true;
9161        } else if (!pi.exported) {
9162            return false;
9163        }
9164
9165        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
9166        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
9167        try {
9168            // check if target holds top-level <provider> permissions
9169            if (!readMet && pi.readPermission != null && considerUidPermissions
9170                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
9171                readMet = true;
9172            }
9173            if (!writeMet && pi.writePermission != null && considerUidPermissions
9174                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
9175                writeMet = true;
9176            }
9177
9178            // track if unprotected read/write is allowed; any denied
9179            // <path-permission> below removes this ability
9180            boolean allowDefaultRead = pi.readPermission == null;
9181            boolean allowDefaultWrite = pi.writePermission == null;
9182
9183            // check if target holds any <path-permission> that match uri
9184            final PathPermission[] pps = pi.pathPermissions;
9185            if (pps != null) {
9186                final String path = grantUri.uri.getPath();
9187                int i = pps.length;
9188                while (i > 0 && (!readMet || !writeMet)) {
9189                    i--;
9190                    PathPermission pp = pps[i];
9191                    if (pp.match(path)) {
9192                        if (!readMet) {
9193                            final String pprperm = pp.getReadPermission();
9194                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9195                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
9196                                    + ": match=" + pp.match(path)
9197                                    + " check=" + pm.checkUidPermission(pprperm, uid));
9198                            if (pprperm != null) {
9199                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
9200                                        == PERMISSION_GRANTED) {
9201                                    readMet = true;
9202                                } else {
9203                                    allowDefaultRead = false;
9204                                }
9205                            }
9206                        }
9207                        if (!writeMet) {
9208                            final String ppwperm = pp.getWritePermission();
9209                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9210                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
9211                                    + ": match=" + pp.match(path)
9212                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
9213                            if (ppwperm != null) {
9214                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
9215                                        == PERMISSION_GRANTED) {
9216                                    writeMet = true;
9217                                } else {
9218                                    allowDefaultWrite = false;
9219                                }
9220                            }
9221                        }
9222                    }
9223                }
9224            }
9225
9226            // grant unprotected <provider> read/write, if not blocked by
9227            // <path-permission> above
9228            if (allowDefaultRead) readMet = true;
9229            if (allowDefaultWrite) writeMet = true;
9230
9231        } catch (RemoteException e) {
9232            return false;
9233        }
9234
9235        return readMet && writeMet;
9236    }
9237
9238    public boolean isAppStartModeDisabled(int uid, String packageName) {
9239        synchronized (this) {
9240            return getAppStartModeLocked(uid, packageName, 0, -1, false, true, false)
9241                    == ActivityManager.APP_START_MODE_DISABLED;
9242        }
9243    }
9244
9245    // Unified app-op and target sdk check
9246    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9247        // Apps that target O+ are always subject to background check
9248        if (packageTargetSdk >= Build.VERSION_CODES.O) {
9249            if (DEBUG_BACKGROUND_CHECK) {
9250                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
9251            }
9252            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9253        }
9254        // ...and legacy apps get an AppOp check
9255        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
9256                uid, packageName);
9257        if (DEBUG_BACKGROUND_CHECK) {
9258            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
9259        }
9260        switch (appop) {
9261            case AppOpsManager.MODE_ALLOWED:
9262                // If force-background-check is enabled, restrict all apps that aren't whitelisted.
9263                if (mForceBackgroundCheck &&
9264                        !UserHandle.isCore(uid) &&
9265                        !isOnDeviceIdleWhitelistLocked(uid)) {
9266                    if (DEBUG_BACKGROUND_CHECK) {
9267                        Slog.i(TAG, "Force background check: " +
9268                                uid + "/" + packageName + " restricted");
9269                    }
9270                    return ActivityManager.APP_START_MODE_DELAYED;
9271                }
9272                return ActivityManager.APP_START_MODE_NORMAL;
9273            case AppOpsManager.MODE_IGNORED:
9274                return ActivityManager.APP_START_MODE_DELAYED;
9275            default:
9276                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9277        }
9278    }
9279
9280    // Service launch is available to apps with run-in-background exemptions but
9281    // some other background operations are not.  If we're doing a check
9282    // of service-launch policy, allow those callers to proceed unrestricted.
9283    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9284        // Persistent app?
9285        if (mPackageManagerInt.isPackagePersistent(packageName)) {
9286            if (DEBUG_BACKGROUND_CHECK) {
9287                Slog.i(TAG, "App " + uid + "/" + packageName
9288                        + " is persistent; not restricted in background");
9289            }
9290            return ActivityManager.APP_START_MODE_NORMAL;
9291        }
9292
9293        // Non-persistent but background whitelisted?
9294        if (uidOnBackgroundWhitelist(uid)) {
9295            if (DEBUG_BACKGROUND_CHECK) {
9296                Slog.i(TAG, "App " + uid + "/" + packageName
9297                        + " on background whitelist; not restricted in background");
9298            }
9299            return ActivityManager.APP_START_MODE_NORMAL;
9300        }
9301
9302        // Is this app on the battery whitelist?
9303        if (isOnDeviceIdleWhitelistLocked(uid)) {
9304            if (DEBUG_BACKGROUND_CHECK) {
9305                Slog.i(TAG, "App " + uid + "/" + packageName
9306                        + " on idle whitelist; not restricted in background");
9307            }
9308            return ActivityManager.APP_START_MODE_NORMAL;
9309        }
9310
9311        // None of the service-policy criteria apply, so we apply the common criteria
9312        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
9313    }
9314
9315    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
9316            int callingPid, boolean alwaysRestrict, boolean disabledOnly, boolean forcedStandby) {
9317        UidRecord uidRec = mActiveUids.get(uid);
9318        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
9319                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
9320                + (uidRec != null ? uidRec.idle : false));
9321        if (uidRec == null || alwaysRestrict || forcedStandby || uidRec.idle) {
9322            boolean ephemeral;
9323            if (uidRec == null) {
9324                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
9325                        UserHandle.getUserId(uid), packageName);
9326            } else {
9327                ephemeral = uidRec.ephemeral;
9328            }
9329
9330            if (ephemeral) {
9331                // We are hard-core about ephemeral apps not running in the background.
9332                return ActivityManager.APP_START_MODE_DISABLED;
9333            } else {
9334                if (disabledOnly) {
9335                    // The caller is only interested in whether app starts are completely
9336                    // disabled for the given package (that is, it is an instant app).  So
9337                    // we don't need to go further, which is all just seeing if we should
9338                    // apply a "delayed" mode for a regular app.
9339                    return ActivityManager.APP_START_MODE_NORMAL;
9340                }
9341                final int startMode = (alwaysRestrict)
9342                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
9343                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
9344                                packageTargetSdk);
9345                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
9346                        + " pkg=" + packageName + " startMode=" + startMode
9347                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
9348                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
9349                    // This is an old app that has been forced into a "compatible as possible"
9350                    // mode of background check.  To increase compatibility, we will allow other
9351                    // foreground apps to cause its services to start.
9352                    if (callingPid >= 0) {
9353                        ProcessRecord proc;
9354                        synchronized (mPidsSelfLocked) {
9355                            proc = mPidsSelfLocked.get(callingPid);
9356                        }
9357                        if (proc != null &&
9358                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
9359                            // Whoever is instigating this is in the foreground, so we will allow it
9360                            // to go through.
9361                            return ActivityManager.APP_START_MODE_NORMAL;
9362                        }
9363                    }
9364                }
9365                return startMode;
9366            }
9367        }
9368        return ActivityManager.APP_START_MODE_NORMAL;
9369    }
9370
9371    /**
9372     * @return whether a UID is in the system, user or temp doze whitelist.
9373     */
9374    boolean isOnDeviceIdleWhitelistLocked(int uid) {
9375        final int appId = UserHandle.getAppId(uid);
9376        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
9377                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
9378                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
9379    }
9380
9381    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
9382        ProviderInfo pi = null;
9383        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
9384        if (cpr != null) {
9385            pi = cpr.info;
9386        } else {
9387            try {
9388                pi = AppGlobals.getPackageManager().resolveContentProvider(
9389                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
9390                        userHandle);
9391            } catch (RemoteException ex) {
9392            }
9393        }
9394        return pi;
9395    }
9396
9397    void grantEphemeralAccessLocked(int userId, Intent intent,
9398            int targetAppId, int ephemeralAppId) {
9399        getPackageManagerInternalLocked().
9400                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
9401    }
9402
9403    @GuardedBy("this")
9404    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
9405        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9406        if (targetUris != null) {
9407            return targetUris.get(grantUri);
9408        }
9409        return null;
9410    }
9411
9412    @GuardedBy("this")
9413    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
9414            String targetPkg, int targetUid, GrantUri grantUri) {
9415        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9416        if (targetUris == null) {
9417            targetUris = Maps.newArrayMap();
9418            mGrantedUriPermissions.put(targetUid, targetUris);
9419        }
9420
9421        UriPermission perm = targetUris.get(grantUri);
9422        if (perm == null) {
9423            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
9424            targetUris.put(grantUri, perm);
9425        }
9426
9427        return perm;
9428    }
9429
9430    @GuardedBy("this")
9431    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
9432            final int modeFlags) {
9433        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
9434        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
9435                : UriPermission.STRENGTH_OWNED;
9436
9437        // Root gets to do everything.
9438        if (uid == 0) {
9439            return true;
9440        }
9441
9442        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9443        if (perms == null) return false;
9444
9445        // First look for exact match
9446        final UriPermission exactPerm = perms.get(grantUri);
9447        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
9448            return true;
9449        }
9450
9451        // No exact match, look for prefixes
9452        final int N = perms.size();
9453        for (int i = 0; i < N; i++) {
9454            final UriPermission perm = perms.valueAt(i);
9455            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
9456                    && perm.getStrength(modeFlags) >= minStrength) {
9457                return true;
9458            }
9459        }
9460
9461        return false;
9462    }
9463
9464    /**
9465     * @param uri This uri must NOT contain an embedded userId.
9466     * @param userId The userId in which the uri is to be resolved.
9467     */
9468    @Override
9469    public int checkUriPermission(Uri uri, int pid, int uid,
9470            final int modeFlags, int userId, IBinder callerToken) {
9471        enforceNotIsolatedCaller("checkUriPermission");
9472
9473        // Another redirected-binder-call permissions check as in
9474        // {@link checkPermissionWithToken}.
9475        Identity tlsIdentity = sCallerIdentity.get();
9476        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9477            uid = tlsIdentity.uid;
9478            pid = tlsIdentity.pid;
9479        }
9480
9481        // Our own process gets to do everything.
9482        if (pid == MY_PID) {
9483            return PackageManager.PERMISSION_GRANTED;
9484        }
9485        synchronized (this) {
9486            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
9487                    ? PackageManager.PERMISSION_GRANTED
9488                    : PackageManager.PERMISSION_DENIED;
9489        }
9490    }
9491
9492    /**
9493     * Check if the targetPkg can be granted permission to access uri by
9494     * the callingUid using the given modeFlags.  Throws a security exception
9495     * if callingUid is not allowed to do this.  Returns the uid of the target
9496     * if the URI permission grant should be performed; returns -1 if it is not
9497     * needed (for example targetPkg already has permission to access the URI).
9498     * If you already know the uid of the target, you can supply it in
9499     * lastTargetUid else set that to -1.
9500     */
9501    @GuardedBy("this")
9502    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9503            final int modeFlags, int lastTargetUid) {
9504        if (!Intent.isAccessUriMode(modeFlags)) {
9505            return -1;
9506        }
9507
9508        if (targetPkg != null) {
9509            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9510                    "Checking grant " + targetPkg + " permission to " + grantUri);
9511        }
9512
9513        final IPackageManager pm = AppGlobals.getPackageManager();
9514
9515        // If this is not a content: uri, we can't do anything with it.
9516        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
9517            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9518                    "Can't grant URI permission for non-content URI: " + grantUri);
9519            return -1;
9520        }
9521
9522        // Bail early if system is trying to hand out permissions directly; it
9523        // must always grant permissions on behalf of someone explicit.
9524        final int callingAppId = UserHandle.getAppId(callingUid);
9525        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
9526            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
9527                // Exempted authority for
9528                // 1. cropping user photos and sharing a generated license html
9529                //    file in Settings app
9530                // 2. sharing a generated license html file in TvSettings app
9531            } else {
9532                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
9533                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
9534                return -1;
9535            }
9536        }
9537
9538        final String authority = grantUri.uri.getAuthority();
9539        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9540                MATCH_DEBUG_TRIAGED_MISSING);
9541        if (pi == null) {
9542            Slog.w(TAG, "No content provider found for permission check: " +
9543                    grantUri.uri.toSafeString());
9544            return -1;
9545        }
9546
9547        int targetUid = lastTargetUid;
9548        if (targetUid < 0 && targetPkg != null) {
9549            try {
9550                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9551                        UserHandle.getUserId(callingUid));
9552                if (targetUid < 0) {
9553                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9554                            "Can't grant URI permission no uid for: " + targetPkg);
9555                    return -1;
9556                }
9557            } catch (RemoteException ex) {
9558                return -1;
9559            }
9560        }
9561
9562        // If we're extending a persistable grant, then we always need to create
9563        // the grant data structure so that take/release APIs work
9564        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
9565            return targetUid;
9566        }
9567
9568        if (targetUid >= 0) {
9569            // First...  does the target actually need this permission?
9570            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
9571                // No need to grant the target this permission.
9572                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9573                        "Target " + targetPkg + " already has full permission to " + grantUri);
9574                return -1;
9575            }
9576        } else {
9577            // First...  there is no target package, so can anyone access it?
9578            boolean allowed = pi.exported;
9579            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9580                if (pi.readPermission != null) {
9581                    allowed = false;
9582                }
9583            }
9584            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9585                if (pi.writePermission != null) {
9586                    allowed = false;
9587                }
9588            }
9589            if (pi.pathPermissions != null) {
9590                final int N = pi.pathPermissions.length;
9591                for (int i=0; i<N; i++) {
9592                    if (pi.pathPermissions[i] != null
9593                            && pi.pathPermissions[i].match(grantUri.uri.getPath())) {
9594                        if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9595                            if (pi.pathPermissions[i].getReadPermission() != null) {
9596                                allowed = false;
9597                            }
9598                        }
9599                        if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9600                            if (pi.pathPermissions[i].getWritePermission() != null) {
9601                                allowed = false;
9602                            }
9603                        }
9604                        break;
9605                    }
9606                }
9607            }
9608            if (allowed) {
9609                return -1;
9610            }
9611        }
9612
9613        /* There is a special cross user grant if:
9614         * - The target is on another user.
9615         * - Apps on the current user can access the uri without any uid permissions.
9616         * In this case, we grant a uri permission, even if the ContentProvider does not normally
9617         * grant uri permissions.
9618         */
9619        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
9620                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
9621                modeFlags, false /*without considering the uid permissions*/);
9622
9623        // Second...  is the provider allowing granting of URI permissions?
9624        if (!specialCrossUserGrant) {
9625            if (!pi.grantUriPermissions) {
9626                throw new SecurityException("Provider " + pi.packageName
9627                        + "/" + pi.name
9628                        + " does not allow granting of Uri permissions (uri "
9629                        + grantUri + ")");
9630            }
9631            if (pi.uriPermissionPatterns != null) {
9632                final int N = pi.uriPermissionPatterns.length;
9633                boolean allowed = false;
9634                for (int i=0; i<N; i++) {
9635                    if (pi.uriPermissionPatterns[i] != null
9636                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
9637                        allowed = true;
9638                        break;
9639                    }
9640                }
9641                if (!allowed) {
9642                    throw new SecurityException("Provider " + pi.packageName
9643                            + "/" + pi.name
9644                            + " does not allow granting of permission to path of Uri "
9645                            + grantUri);
9646                }
9647            }
9648        }
9649
9650        // Third...  does the caller itself have permission to access
9651        // this uri?
9652        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9653            // Require they hold a strong enough Uri permission
9654            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
9655                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
9656                    throw new SecurityException(
9657                            "UID " + callingUid + " does not have permission to " + grantUri
9658                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
9659                                    + "or related APIs");
9660                } else {
9661                    throw new SecurityException(
9662                            "UID " + callingUid + " does not have permission to " + grantUri);
9663                }
9664            }
9665        }
9666        return targetUid;
9667    }
9668
9669    /**
9670     * @param uri This uri must NOT contain an embedded userId.
9671     * @param userId The userId in which the uri is to be resolved.
9672     */
9673    @Override
9674    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
9675            final int modeFlags, int userId) {
9676        enforceNotIsolatedCaller("checkGrantUriPermission");
9677        synchronized(this) {
9678            return checkGrantUriPermissionLocked(callingUid, targetPkg,
9679                    new GrantUri(userId, uri, false), modeFlags, -1);
9680        }
9681    }
9682
9683    @GuardedBy("this")
9684    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
9685            final int modeFlags, UriPermissionOwner owner) {
9686        if (!Intent.isAccessUriMode(modeFlags)) {
9687            return;
9688        }
9689
9690        // So here we are: the caller has the assumed permission
9691        // to the uri, and the target doesn't.  Let's now give this to
9692        // the target.
9693
9694        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9695                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
9696
9697        final String authority = grantUri.uri.getAuthority();
9698        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9699                MATCH_DEBUG_TRIAGED_MISSING);
9700        if (pi == null) {
9701            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
9702            return;
9703        }
9704
9705        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
9706            grantUri.prefix = true;
9707        }
9708        final UriPermission perm = findOrCreateUriPermissionLocked(
9709                pi.packageName, targetPkg, targetUid, grantUri);
9710        perm.grantModes(modeFlags, owner);
9711    }
9712
9713    @GuardedBy("this")
9714    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9715            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9716        if (targetPkg == null) {
9717            throw new NullPointerException("targetPkg");
9718        }
9719        int targetUid;
9720        final IPackageManager pm = AppGlobals.getPackageManager();
9721        try {
9722            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9723        } catch (RemoteException ex) {
9724            return;
9725        }
9726
9727        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9728                targetUid);
9729        if (targetUid < 0) {
9730            return;
9731        }
9732
9733        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9734                owner);
9735    }
9736
9737    static class NeededUriGrants extends ArrayList<GrantUri> {
9738        final String targetPkg;
9739        final int targetUid;
9740        final int flags;
9741
9742        NeededUriGrants(String targetPkg, int targetUid, int flags) {
9743            this.targetPkg = targetPkg;
9744            this.targetUid = targetUid;
9745            this.flags = flags;
9746        }
9747
9748        void writeToProto(ProtoOutputStream proto, long fieldId) {
9749            long token = proto.start(fieldId);
9750            proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
9751            proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
9752            proto.write(NeededUriGrantsProto.FLAGS, flags);
9753
9754            final int N = this.size();
9755            for (int i=0; i<N; i++) {
9756                this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
9757            }
9758            proto.end(token);
9759        }
9760    }
9761
9762    /**
9763     * Like checkGrantUriPermissionLocked, but takes an Intent.
9764     */
9765    @GuardedBy("this")
9766    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9767            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9768        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9769                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9770                + " clip=" + (intent != null ? intent.getClipData() : null)
9771                + " from " + intent + "; flags=0x"
9772                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9773
9774        if (targetPkg == null) {
9775            throw new NullPointerException("targetPkg");
9776        }
9777
9778        if (intent == null) {
9779            return null;
9780        }
9781        Uri data = intent.getData();
9782        ClipData clip = intent.getClipData();
9783        if (data == null && clip == null) {
9784            return null;
9785        }
9786        // Default userId for uris in the intent (if they don't specify it themselves)
9787        int contentUserHint = intent.getContentUserHint();
9788        if (contentUserHint == UserHandle.USER_CURRENT) {
9789            contentUserHint = UserHandle.getUserId(callingUid);
9790        }
9791        final IPackageManager pm = AppGlobals.getPackageManager();
9792        int targetUid;
9793        if (needed != null) {
9794            targetUid = needed.targetUid;
9795        } else {
9796            try {
9797                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9798                        targetUserId);
9799            } catch (RemoteException ex) {
9800                return null;
9801            }
9802            if (targetUid < 0) {
9803                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9804                        "Can't grant URI permission no uid for: " + targetPkg
9805                        + " on user " + targetUserId);
9806                return null;
9807            }
9808        }
9809        if (data != null) {
9810            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9811            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9812                    targetUid);
9813            if (targetUid > 0) {
9814                if (needed == null) {
9815                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
9816                }
9817                needed.add(grantUri);
9818            }
9819        }
9820        if (clip != null) {
9821            for (int i=0; i<clip.getItemCount(); i++) {
9822                Uri uri = clip.getItemAt(i).getUri();
9823                if (uri != null) {
9824                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9825                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9826                            targetUid);
9827                    if (targetUid > 0) {
9828                        if (needed == null) {
9829                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
9830                        }
9831                        needed.add(grantUri);
9832                    }
9833                } else {
9834                    Intent clipIntent = clip.getItemAt(i).getIntent();
9835                    if (clipIntent != null) {
9836                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9837                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9838                        if (newNeeded != null) {
9839                            needed = newNeeded;
9840                        }
9841                    }
9842                }
9843            }
9844        }
9845
9846        return needed;
9847    }
9848
9849    /**
9850     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9851     */
9852    @GuardedBy("this")
9853    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9854            UriPermissionOwner owner) {
9855        if (needed != null) {
9856            for (int i=0; i<needed.size(); i++) {
9857                GrantUri grantUri = needed.get(i);
9858                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9859                        grantUri, needed.flags, owner);
9860            }
9861        }
9862    }
9863
9864    @GuardedBy("this")
9865    void grantUriPermissionFromIntentLocked(int callingUid,
9866            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9867        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9868                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9869        if (needed == null) {
9870            return;
9871        }
9872
9873        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9874    }
9875
9876    /**
9877     * @param uri This uri must NOT contain an embedded userId.
9878     * @param userId The userId in which the uri is to be resolved.
9879     */
9880    @Override
9881    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9882            final int modeFlags, int userId) {
9883        enforceNotIsolatedCaller("grantUriPermission");
9884        GrantUri grantUri = new GrantUri(userId, uri, false);
9885        synchronized(this) {
9886            final ProcessRecord r = getRecordForAppLocked(caller);
9887            if (r == null) {
9888                throw new SecurityException("Unable to find app for caller "
9889                        + caller
9890                        + " when granting permission to uri " + grantUri);
9891            }
9892            if (targetPkg == null) {
9893                throw new IllegalArgumentException("null target");
9894            }
9895            if (grantUri == null) {
9896                throw new IllegalArgumentException("null uri");
9897            }
9898
9899            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9900                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9901                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9902                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9903
9904            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9905                    UserHandle.getUserId(r.uid));
9906        }
9907    }
9908
9909    @GuardedBy("this")
9910    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9911        if (perm.modeFlags == 0) {
9912            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9913                    perm.targetUid);
9914            if (perms != null) {
9915                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9916                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9917
9918                perms.remove(perm.uri);
9919                if (perms.isEmpty()) {
9920                    mGrantedUriPermissions.remove(perm.targetUid);
9921                }
9922            }
9923        }
9924    }
9925
9926    @GuardedBy("this")
9927    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9928            final int modeFlags) {
9929        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9930                "Revoking all granted permissions to " + grantUri);
9931
9932        final IPackageManager pm = AppGlobals.getPackageManager();
9933        final String authority = grantUri.uri.getAuthority();
9934        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9935                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9936        if (pi == null) {
9937            Slog.w(TAG, "No content provider found for permission revoke: "
9938                    + grantUri.toSafeString());
9939            return;
9940        }
9941
9942        // Does the caller have this permission on the URI?
9943        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9944            // If they don't have direct access to the URI, then revoke any
9945            // ownerless URI permissions that have been granted to them.
9946            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9947            if (perms != null) {
9948                boolean persistChanged = false;
9949                for (int i = perms.size()-1; i >= 0; i--) {
9950                    final UriPermission perm = perms.valueAt(i);
9951                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9952                        continue;
9953                    }
9954                    if (perm.uri.sourceUserId == grantUri.sourceUserId
9955                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9956                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9957                                "Revoking non-owned " + perm.targetUid
9958                                + " permission to " + perm.uri);
9959                        persistChanged |= perm.revokeModes(
9960                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9961                        if (perm.modeFlags == 0) {
9962                            perms.removeAt(i);
9963                        }
9964                    }
9965                }
9966                if (perms.isEmpty()) {
9967                    mGrantedUriPermissions.remove(callingUid);
9968                }
9969                if (persistChanged) {
9970                    schedulePersistUriGrants();
9971                }
9972            }
9973            return;
9974        }
9975
9976        boolean persistChanged = false;
9977
9978        // Go through all of the permissions and remove any that match.
9979        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9980            final int targetUid = mGrantedUriPermissions.keyAt(i);
9981            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9982
9983            for (int j = perms.size()-1; j >= 0; j--) {
9984                final UriPermission perm = perms.valueAt(j);
9985                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9986                    continue;
9987                }
9988                if (perm.uri.sourceUserId == grantUri.sourceUserId
9989                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9990                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9991                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9992                    persistChanged |= perm.revokeModes(
9993                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9994                            targetPackage == null);
9995                    if (perm.modeFlags == 0) {
9996                        perms.removeAt(j);
9997                    }
9998                }
9999            }
10000
10001            if (perms.isEmpty()) {
10002                mGrantedUriPermissions.removeAt(i);
10003            }
10004        }
10005
10006        if (persistChanged) {
10007            schedulePersistUriGrants();
10008        }
10009    }
10010
10011    /**
10012     * @param uri This uri must NOT contain an embedded userId.
10013     * @param userId The userId in which the uri is to be resolved.
10014     */
10015    @Override
10016    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
10017            final int modeFlags, int userId) {
10018        enforceNotIsolatedCaller("revokeUriPermission");
10019        synchronized(this) {
10020            final ProcessRecord r = getRecordForAppLocked(caller);
10021            if (r == null) {
10022                throw new SecurityException("Unable to find app for caller "
10023                        + caller
10024                        + " when revoking permission to uri " + uri);
10025            }
10026            if (uri == null) {
10027                Slog.w(TAG, "revokeUriPermission: null uri");
10028                return;
10029            }
10030
10031            if (!Intent.isAccessUriMode(modeFlags)) {
10032                return;
10033            }
10034
10035            final String authority = uri.getAuthority();
10036            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
10037                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
10038            if (pi == null) {
10039                Slog.w(TAG, "No content provider found for permission revoke: "
10040                        + uri.toSafeString());
10041                return;
10042            }
10043
10044            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
10045                    modeFlags);
10046        }
10047    }
10048
10049    /**
10050     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
10051     * given package.
10052     *
10053     * @param packageName Package name to match, or {@code null} to apply to all
10054     *            packages.
10055     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
10056     *            to all users.
10057     * @param persistable If persistable grants should be removed.
10058     * @param targetOnly When {@code true}, only remove permissions where the app is the target,
10059     * not source.
10060     */
10061    @GuardedBy("this")
10062    private void removeUriPermissionsForPackageLocked(
10063            String packageName, int userHandle, boolean persistable, boolean targetOnly) {
10064        if (userHandle == UserHandle.USER_ALL && packageName == null) {
10065            throw new IllegalArgumentException("Must narrow by either package or user");
10066        }
10067
10068        boolean persistChanged = false;
10069
10070        int N = mGrantedUriPermissions.size();
10071        for (int i = 0; i < N; i++) {
10072            final int targetUid = mGrantedUriPermissions.keyAt(i);
10073            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10074
10075            // Only inspect grants matching user
10076            if (userHandle == UserHandle.USER_ALL
10077                    || userHandle == UserHandle.getUserId(targetUid)) {
10078                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
10079                    final UriPermission perm = it.next();
10080
10081                    // Only inspect grants matching package
10082                    if (packageName == null || (!targetOnly && perm.sourcePkg.equals(packageName))
10083                            || perm.targetPkg.equals(packageName)) {
10084                        // Hacky solution as part of fixing a security bug; ignore
10085                        // grants associated with DownloadManager so we don't have
10086                        // to immediately launch it to regrant the permissions
10087                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
10088                                && !persistable) continue;
10089
10090                        persistChanged |= perm.revokeModes(persistable
10091                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
10092
10093                        // Only remove when no modes remain; any persisted grants
10094                        // will keep this alive.
10095                        if (perm.modeFlags == 0) {
10096                            it.remove();
10097                        }
10098                    }
10099                }
10100
10101                if (perms.isEmpty()) {
10102                    mGrantedUriPermissions.remove(targetUid);
10103                    N--;
10104                    i--;
10105                }
10106            }
10107        }
10108
10109        if (persistChanged) {
10110            schedulePersistUriGrants();
10111        }
10112    }
10113
10114    @Override
10115    public IBinder newUriPermissionOwner(String name) {
10116        enforceNotIsolatedCaller("newUriPermissionOwner");
10117        synchronized(this) {
10118            UriPermissionOwner owner = new UriPermissionOwner(this, name);
10119            return owner.getExternalTokenLocked();
10120        }
10121    }
10122
10123    @Override
10124    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
10125        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
10126        synchronized(this) {
10127            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10128            if (r == null) {
10129                throw new IllegalArgumentException("Activity does not exist; token="
10130                        + activityToken);
10131            }
10132            return r.getUriPermissionsLocked().getExternalTokenLocked();
10133        }
10134    }
10135    /**
10136     * @param uri This uri must NOT contain an embedded userId.
10137     * @param sourceUserId The userId in which the uri is to be resolved.
10138     * @param targetUserId The userId of the app that receives the grant.
10139     */
10140    @Override
10141    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
10142            final int modeFlags, int sourceUserId, int targetUserId) {
10143        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
10144                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
10145                "grantUriPermissionFromOwner", null);
10146        synchronized(this) {
10147            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
10148            if (owner == null) {
10149                throw new IllegalArgumentException("Unknown owner: " + token);
10150            }
10151            if (fromUid != Binder.getCallingUid()) {
10152                if (Binder.getCallingUid() != myUid()) {
10153                    // Only system code can grant URI permissions on behalf
10154                    // of other users.
10155                    throw new SecurityException("nice try");
10156                }
10157            }
10158            if (targetPkg == null) {
10159                throw new IllegalArgumentException("null target");
10160            }
10161            if (uri == null) {
10162                throw new IllegalArgumentException("null uri");
10163            }
10164
10165            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
10166                    modeFlags, owner, targetUserId);
10167        }
10168    }
10169
10170    /**
10171     * @param uri This uri must NOT contain an embedded userId.
10172     * @param userId The userId in which the uri is to be resolved.
10173     */
10174    @Override
10175    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
10176        synchronized(this) {
10177            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
10178            if (owner == null) {
10179                throw new IllegalArgumentException("Unknown owner: " + token);
10180            }
10181
10182            if (uri == null) {
10183                owner.removeUriPermissionsLocked(mode);
10184            } else {
10185                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
10186                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
10187            }
10188        }
10189    }
10190
10191    private void schedulePersistUriGrants() {
10192        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
10193            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
10194                    10 * DateUtils.SECOND_IN_MILLIS);
10195        }
10196    }
10197
10198    private void writeGrantedUriPermissions() {
10199        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
10200
10201        final long startTime = SystemClock.uptimeMillis();
10202
10203        // Snapshot permissions so we can persist without lock
10204        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
10205        synchronized (this) {
10206            final int size = mGrantedUriPermissions.size();
10207            for (int i = 0; i < size; i++) {
10208                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10209                for (UriPermission perm : perms.values()) {
10210                    if (perm.persistedModeFlags != 0) {
10211                        persist.add(perm.snapshot());
10212                    }
10213                }
10214            }
10215        }
10216
10217        FileOutputStream fos = null;
10218        try {
10219            fos = mGrantFile.startWrite(startTime);
10220
10221            XmlSerializer out = new FastXmlSerializer();
10222            out.setOutput(fos, StandardCharsets.UTF_8.name());
10223            out.startDocument(null, true);
10224            out.startTag(null, TAG_URI_GRANTS);
10225            for (UriPermission.Snapshot perm : persist) {
10226                out.startTag(null, TAG_URI_GRANT);
10227                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
10228                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
10229                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
10230                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
10231                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
10232                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
10233                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
10234                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
10235                out.endTag(null, TAG_URI_GRANT);
10236            }
10237            out.endTag(null, TAG_URI_GRANTS);
10238            out.endDocument();
10239
10240            mGrantFile.finishWrite(fos);
10241        } catch (IOException e) {
10242            if (fos != null) {
10243                mGrantFile.failWrite(fos);
10244            }
10245        }
10246    }
10247
10248    @GuardedBy("this")
10249    private void readGrantedUriPermissionsLocked() {
10250        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
10251
10252        final long now = System.currentTimeMillis();
10253
10254        FileInputStream fis = null;
10255        try {
10256            fis = mGrantFile.openRead();
10257            final XmlPullParser in = Xml.newPullParser();
10258            in.setInput(fis, StandardCharsets.UTF_8.name());
10259
10260            int type;
10261            while ((type = in.next()) != END_DOCUMENT) {
10262                final String tag = in.getName();
10263                if (type == START_TAG) {
10264                    if (TAG_URI_GRANT.equals(tag)) {
10265                        final int sourceUserId;
10266                        final int targetUserId;
10267                        final int userHandle = readIntAttribute(in,
10268                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
10269                        if (userHandle != UserHandle.USER_NULL) {
10270                            // For backwards compatibility.
10271                            sourceUserId = userHandle;
10272                            targetUserId = userHandle;
10273                        } else {
10274                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
10275                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
10276                        }
10277                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
10278                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
10279                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
10280                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
10281                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
10282                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
10283
10284                        // Sanity check that provider still belongs to source package
10285                        // Both direct boot aware and unaware packages are fine as we
10286                        // will do filtering at query time to avoid multiple parsing.
10287                        final ProviderInfo pi = getProviderInfoLocked(
10288                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
10289                                        | MATCH_DIRECT_BOOT_UNAWARE);
10290                        if (pi != null && sourcePkg.equals(pi.packageName)) {
10291                            int targetUid = -1;
10292                            try {
10293                                targetUid = AppGlobals.getPackageManager().getPackageUid(
10294                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
10295                            } catch (RemoteException e) {
10296                            }
10297                            if (targetUid != -1) {
10298                                final UriPermission perm = findOrCreateUriPermissionLocked(
10299                                        sourcePkg, targetPkg, targetUid,
10300                                        new GrantUri(sourceUserId, uri, prefix));
10301                                perm.initPersistedModes(modeFlags, createdTime);
10302                            }
10303                        } else {
10304                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
10305                                    + " but instead found " + pi);
10306                        }
10307                    }
10308                }
10309            }
10310        } catch (FileNotFoundException e) {
10311            // Missing grants is okay
10312        } catch (IOException e) {
10313            Slog.wtf(TAG, "Failed reading Uri grants", e);
10314        } catch (XmlPullParserException e) {
10315            Slog.wtf(TAG, "Failed reading Uri grants", e);
10316        } finally {
10317            IoUtils.closeQuietly(fis);
10318        }
10319    }
10320
10321    /**
10322     * @param uri This uri must NOT contain an embedded userId.
10323     * @param toPackage Name of package whose uri is being granted to (if {@code null}, uses
10324     * calling uid)
10325     * @param userId The userId in which the uri is to be resolved.
10326     */
10327    @Override
10328    public void takePersistableUriPermission(Uri uri, final int modeFlags,
10329            @Nullable String toPackage, int userId) {
10330        final int uid;
10331        if (toPackage != null) {
10332            enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10333                    "takePersistableUriPermission");
10334            uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10335        } else {
10336            enforceNotIsolatedCaller("takePersistableUriPermission");
10337            uid = Binder.getCallingUid();
10338        }
10339
10340        Preconditions.checkFlagsArgument(modeFlags,
10341                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10342
10343        synchronized (this) {
10344            boolean persistChanged = false;
10345            GrantUri grantUri = new GrantUri(userId, uri, false);
10346
10347            UriPermission exactPerm = findUriPermissionLocked(uid, grantUri);
10348            UriPermission prefixPerm = findUriPermissionLocked(uid,
10349                    new GrantUri(userId, uri, true));
10350
10351            final boolean exactValid = (exactPerm != null)
10352                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
10353            final boolean prefixValid = (prefixPerm != null)
10354                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
10355
10356            if (!(exactValid || prefixValid)) {
10357                throw new SecurityException("No persistable permission grants found for UID "
10358                        + uid + " and Uri " + grantUri.toSafeString());
10359            }
10360
10361            if (exactValid) {
10362                persistChanged |= exactPerm.takePersistableModes(modeFlags);
10363            }
10364            if (prefixValid) {
10365                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
10366            }
10367
10368            persistChanged |= maybePrunePersistedUriGrantsLocked(uid);
10369
10370            if (persistChanged) {
10371                schedulePersistUriGrants();
10372            }
10373        }
10374    }
10375
10376    /**
10377     * @param uri This uri must NOT contain an embedded userId.
10378     * @param toPackage Name of the target package whose uri is being released (if {@code null},
10379     * uses calling uid)
10380     * @param userId The userId in which the uri is to be resolved.
10381     */
10382    @Override
10383    public void releasePersistableUriPermission(Uri uri, final int modeFlags,
10384            @Nullable String toPackage, int userId) {
10385
10386        final int uid;
10387        if (toPackage != null) {
10388            enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10389                    "releasePersistableUriPermission");
10390            uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10391        } else {
10392            enforceNotIsolatedCaller("releasePersistableUriPermission");
10393            uid = Binder.getCallingUid();
10394        }
10395
10396        Preconditions.checkFlagsArgument(modeFlags,
10397                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10398
10399        synchronized (this) {
10400            boolean persistChanged = false;
10401
10402            UriPermission exactPerm = findUriPermissionLocked(uid,
10403                    new GrantUri(userId, uri, false));
10404            UriPermission prefixPerm = findUriPermissionLocked(uid,
10405                    new GrantUri(userId, uri, true));
10406            if (exactPerm == null && prefixPerm == null && toPackage == null) {
10407                throw new SecurityException("No permission grants found for UID " + uid
10408                        + " and Uri " + uri.toSafeString());
10409            }
10410
10411            if (exactPerm != null) {
10412                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
10413                removeUriPermissionIfNeededLocked(exactPerm);
10414            }
10415            if (prefixPerm != null) {
10416                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
10417                removeUriPermissionIfNeededLocked(prefixPerm);
10418            }
10419
10420            if (persistChanged) {
10421                schedulePersistUriGrants();
10422            }
10423        }
10424    }
10425
10426    /**
10427     * Prune any older {@link UriPermission} for the given UID until outstanding
10428     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
10429     *
10430     * @return if any mutations occured that require persisting.
10431     */
10432    @GuardedBy("this")
10433    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
10434        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
10435        if (perms == null) return false;
10436        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
10437
10438        final ArrayList<UriPermission> persisted = Lists.newArrayList();
10439        for (UriPermission perm : perms.values()) {
10440            if (perm.persistedModeFlags != 0) {
10441                persisted.add(perm);
10442            }
10443        }
10444
10445        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
10446        if (trimCount <= 0) return false;
10447
10448        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
10449        for (int i = 0; i < trimCount; i++) {
10450            final UriPermission perm = persisted.get(i);
10451
10452            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10453                    "Trimming grant created at " + perm.persistedCreateTime);
10454
10455            perm.releasePersistableModes(~0);
10456            removeUriPermissionIfNeededLocked(perm);
10457        }
10458
10459        return true;
10460    }
10461
10462    @Override
10463    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
10464            String packageName, boolean incoming) {
10465        enforceNotIsolatedCaller("getPersistedUriPermissions");
10466        Preconditions.checkNotNull(packageName, "packageName");
10467
10468        final int callingUid = Binder.getCallingUid();
10469        final int callingUserId = UserHandle.getUserId(callingUid);
10470        final IPackageManager pm = AppGlobals.getPackageManager();
10471        try {
10472            final int packageUid = pm.getPackageUid(packageName,
10473                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
10474            if (packageUid != callingUid) {
10475                throw new SecurityException(
10476                        "Package " + packageName + " does not belong to calling UID " + callingUid);
10477            }
10478        } catch (RemoteException e) {
10479            throw new SecurityException("Failed to verify package name ownership");
10480        }
10481
10482        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10483        synchronized (this) {
10484            if (incoming) {
10485                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10486                        callingUid);
10487                if (perms == null) {
10488                    Slog.w(TAG, "No permission grants found for " + packageName);
10489                } else {
10490                    for (int j = 0; j < perms.size(); j++) {
10491                        final UriPermission perm = perms.valueAt(j);
10492                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
10493                            result.add(perm.buildPersistedPublicApiObject());
10494                        }
10495                    }
10496                }
10497            } else {
10498                final int size = mGrantedUriPermissions.size();
10499                for (int i = 0; i < size; i++) {
10500                    final ArrayMap<GrantUri, UriPermission> perms =
10501                            mGrantedUriPermissions.valueAt(i);
10502                    for (int j = 0; j < perms.size(); j++) {
10503                        final UriPermission perm = perms.valueAt(j);
10504                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
10505                            result.add(perm.buildPersistedPublicApiObject());
10506                        }
10507                    }
10508                }
10509            }
10510        }
10511        return new ParceledListSlice<android.content.UriPermission>(result);
10512    }
10513
10514    @Override
10515    public ParceledListSlice<GrantedUriPermission> getGrantedUriPermissions(
10516            @Nullable String packageName, int userId) {
10517        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10518                "getGrantedUriPermissions");
10519
10520        final List<GrantedUriPermission> result = new ArrayList<>();
10521        synchronized (this) {
10522            final int size = mGrantedUriPermissions.size();
10523            for (int i = 0; i < size; i++) {
10524                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10525                for (int j = 0; j < perms.size(); j++) {
10526                    final UriPermission perm = perms.valueAt(j);
10527                    if ((packageName == null || packageName.equals(perm.targetPkg))
10528                            && perm.targetUserId == userId
10529                            && perm.persistedModeFlags != 0) {
10530                        result.add(perm.buildGrantedUriPermission());
10531                    }
10532                }
10533            }
10534        }
10535        return new ParceledListSlice<>(result);
10536    }
10537
10538    @Override
10539    public void clearGrantedUriPermissions(String packageName, int userId) {
10540        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
10541                "clearGrantedUriPermissions");
10542        synchronized(this) {
10543            removeUriPermissionsForPackageLocked(packageName, userId, true, true);
10544        }
10545    }
10546
10547    @Override
10548    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
10549        synchronized (this) {
10550            ProcessRecord app =
10551                who != null ? getRecordForAppLocked(who) : null;
10552            if (app == null) return;
10553
10554            Message msg = Message.obtain();
10555            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
10556            msg.obj = app;
10557            msg.arg1 = waiting ? 1 : 0;
10558            mUiHandler.sendMessage(msg);
10559        }
10560    }
10561
10562    @Override
10563    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
10564        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
10565        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
10566        outInfo.availMem = getFreeMemory();
10567        outInfo.totalMem = getTotalMemory();
10568        outInfo.threshold = homeAppMem;
10569        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
10570        outInfo.hiddenAppThreshold = cachedAppMem;
10571        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
10572                ProcessList.SERVICE_ADJ);
10573        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
10574                ProcessList.VISIBLE_APP_ADJ);
10575        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
10576                ProcessList.FOREGROUND_APP_ADJ);
10577    }
10578
10579    // =========================================================
10580    // TASK MANAGEMENT
10581    // =========================================================
10582
10583    @Override
10584    public List<IBinder> getAppTasks(String callingPackage) {
10585        int callingUid = Binder.getCallingUid();
10586        long ident = Binder.clearCallingIdentity();
10587        try {
10588            synchronized(this) {
10589                return mRecentTasks.getAppTasksList(callingUid, callingPackage);
10590            }
10591        } finally {
10592            Binder.restoreCallingIdentity(ident);
10593        }
10594    }
10595
10596    @Override
10597    public List<RunningTaskInfo> getTasks(int maxNum) {
10598       return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
10599    }
10600
10601    @Override
10602    public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
10603            @WindowingMode int ignoreWindowingMode) {
10604        final int callingUid = Binder.getCallingUid();
10605        ArrayList<RunningTaskInfo> list = new ArrayList<>();
10606
10607        synchronized(this) {
10608            if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
10609
10610            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
10611                    callingUid);
10612            mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
10613                    ignoreWindowingMode, callingUid, allowed);
10614        }
10615
10616        return list;
10617    }
10618
10619    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
10620        if (mRecentTasks.isCallerRecents(callingUid)) {
10621            // Always allow the recents component to get tasks
10622            return true;
10623        }
10624
10625        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
10626                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
10627        if (!allowed) {
10628            if (checkPermission(android.Manifest.permission.GET_TASKS,
10629                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
10630                // Temporary compatibility: some existing apps on the system image may
10631                // still be requesting the old permission and not switched to the new
10632                // one; if so, we'll still allow them full access.  This means we need
10633                // to see if they are holding the old permission and are a system app.
10634                try {
10635                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
10636                        allowed = true;
10637                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10638                                + " is using old GET_TASKS but privileged; allowing");
10639                    }
10640                } catch (RemoteException e) {
10641                }
10642            }
10643        }
10644        if (!allowed) {
10645            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10646                    + " does not hold REAL_GET_TASKS; limiting output");
10647        }
10648        return allowed;
10649    }
10650
10651    @Override
10652    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
10653            int userId) {
10654        final int callingUid = Binder.getCallingUid();
10655        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
10656                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
10657        final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
10658                callingUid);
10659        final boolean detailed = checkCallingPermission(
10660                android.Manifest.permission.GET_DETAILED_TASKS)
10661                        == PackageManager.PERMISSION_GRANTED;
10662
10663        synchronized (this) {
10664            return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
10665                    callingUid);
10666        }
10667    }
10668
10669    @Override
10670    public ActivityManager.TaskDescription getTaskDescription(int id) {
10671        synchronized (this) {
10672            enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
10673            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10674                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10675            if (tr != null) {
10676                return tr.lastTaskDescription;
10677            }
10678        }
10679        return null;
10680    }
10681
10682    @Override
10683    public int addAppTask(IBinder activityToken, Intent intent,
10684            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10685        final int callingUid = Binder.getCallingUid();
10686        final long callingIdent = Binder.clearCallingIdentity();
10687
10688        try {
10689            synchronized (this) {
10690                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10691                if (r == null) {
10692                    throw new IllegalArgumentException("Activity does not exist; token="
10693                            + activityToken);
10694                }
10695                ComponentName comp = intent.getComponent();
10696                if (comp == null) {
10697                    throw new IllegalArgumentException("Intent " + intent
10698                            + " must specify explicit component");
10699                }
10700                if (thumbnail.getWidth() != mThumbnailWidth
10701                        || thumbnail.getHeight() != mThumbnailHeight) {
10702                    throw new IllegalArgumentException("Bad thumbnail size: got "
10703                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10704                            + mThumbnailWidth + "x" + mThumbnailHeight);
10705                }
10706                if (intent.getSelector() != null) {
10707                    intent.setSelector(null);
10708                }
10709                if (intent.getSourceBounds() != null) {
10710                    intent.setSourceBounds(null);
10711                }
10712                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10713                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10714                        // The caller has added this as an auto-remove task...  that makes no
10715                        // sense, so turn off auto-remove.
10716                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10717                    }
10718                }
10719                final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
10720                        STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
10721                if (ainfo.applicationInfo.uid != callingUid) {
10722                    throw new SecurityException(
10723                            "Can't add task for another application: target uid="
10724                            + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10725                }
10726
10727                final ActivityStack stack = r.getStack();
10728                final TaskRecord task = stack.createTaskRecord(
10729                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
10730                        null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
10731                if (!mRecentTasks.addToBottom(task)) {
10732                    // The app has too many tasks already and we can't add any more
10733                    stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
10734                    return INVALID_TASK_ID;
10735                }
10736                task.lastTaskDescription.copyFrom(description);
10737
10738                // TODO: Send the thumbnail to WM to store it.
10739
10740                return task.taskId;
10741            }
10742        } finally {
10743            Binder.restoreCallingIdentity(callingIdent);
10744        }
10745    }
10746
10747    @Override
10748    public Point getAppTaskThumbnailSize() {
10749        synchronized (this) {
10750            return new Point(mThumbnailWidth,  mThumbnailHeight);
10751        }
10752    }
10753
10754    @Override
10755    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10756        synchronized (this) {
10757            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10758            if (r != null) {
10759                r.setTaskDescription(td);
10760                final TaskRecord task = r.getTask();
10761                task.updateTaskDescription();
10762                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10763            }
10764        }
10765    }
10766
10767    @Override
10768    public void setTaskResizeable(int taskId, int resizeableMode) {
10769        synchronized (this) {
10770            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10771                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10772            if (task == null) {
10773                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10774                return;
10775            }
10776            task.setResizeMode(resizeableMode);
10777        }
10778    }
10779
10780    @Override
10781    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10782        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10783        long ident = Binder.clearCallingIdentity();
10784        try {
10785            synchronized (this) {
10786                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10787                if (task == null) {
10788                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10789                    return;
10790                }
10791                // Place the task in the right stack if it isn't there already based on
10792                // the requested bounds.
10793                // The stack transition logic is:
10794                // - a null bounds on a freeform task moves that task to fullscreen
10795                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10796                //   that task to freeform
10797                // - otherwise the task is not moved
10798                ActivityStack stack = task.getStack();
10799                if (!task.getWindowConfiguration().canResizeTask()) {
10800                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10801                }
10802                if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
10803                    stack = stack.getDisplay().getOrCreateStack(
10804                            WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10805                } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
10806                    stack = stack.getDisplay().getOrCreateStack(
10807                            WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
10808                }
10809
10810                // Reparent the task to the right stack if necessary
10811                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10812                if (stack != task.getStack()) {
10813                    // Defer resume until the task is resized below
10814                    task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10815                            DEFER_RESUME, "resizeTask");
10816                    preserveWindow = false;
10817                }
10818
10819                // After reparenting (which only resizes the task to the stack bounds), resize the
10820                // task to the actual bounds provided
10821                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10822            }
10823        } finally {
10824            Binder.restoreCallingIdentity(ident);
10825        }
10826    }
10827
10828    @Override
10829    public Rect getTaskBounds(int taskId) {
10830        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10831        long ident = Binder.clearCallingIdentity();
10832        Rect rect = new Rect();
10833        try {
10834            synchronized (this) {
10835                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10836                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10837                if (task == null) {
10838                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10839                    return rect;
10840                }
10841                if (task.getStack() != null) {
10842                    // Return the bounds from window manager since it will be adjusted for various
10843                    // things like the presense of a docked stack for tasks that aren't resizeable.
10844                    task.getWindowContainerBounds(rect);
10845                } else {
10846                    // Task isn't in window manager yet since it isn't associated with a stack.
10847                    // Return the persist value from activity manager
10848                    if (!task.matchParentBounds()) {
10849                        rect.set(task.getBounds());
10850                    } else if (task.mLastNonFullscreenBounds != null) {
10851                        rect.set(task.mLastNonFullscreenBounds);
10852                    }
10853                }
10854            }
10855        } finally {
10856            Binder.restoreCallingIdentity(ident);
10857        }
10858        return rect;
10859    }
10860
10861    @Override
10862    public void cancelTaskWindowTransition(int taskId) {
10863        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10864                "cancelTaskWindowTransition()");
10865        final long ident = Binder.clearCallingIdentity();
10866        try {
10867            synchronized (this) {
10868                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10869                        MATCH_TASK_IN_STACKS_ONLY);
10870                if (task == null) {
10871                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10872                    return;
10873                }
10874                task.cancelWindowTransition();
10875            }
10876        } finally {
10877            Binder.restoreCallingIdentity(ident);
10878        }
10879    }
10880
10881    @Override
10882    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10883        enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10884        final long ident = Binder.clearCallingIdentity();
10885        try {
10886            final TaskRecord task;
10887            synchronized (this) {
10888                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10889                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10890                if (task == null) {
10891                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10892                    return null;
10893                }
10894            }
10895            // Don't call this while holding the lock as this operation might hit the disk.
10896            return task.getSnapshot(reducedResolution);
10897        } finally {
10898            Binder.restoreCallingIdentity(ident);
10899        }
10900    }
10901
10902    @Override
10903    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10904        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10905                userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
10906
10907        final File passedIconFile = new File(filePath);
10908        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10909                passedIconFile.getName());
10910        if (!legitIconFile.getPath().equals(filePath)
10911                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10912            throw new IllegalArgumentException("Bad file path: " + filePath
10913                    + " passed for userId " + userId);
10914        }
10915        return mRecentTasks.getTaskDescriptionIcon(filePath);
10916    }
10917
10918    @Override
10919    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10920            throws RemoteException {
10921        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
10922        final ActivityOptions activityOptions = safeOptions != null
10923                ? safeOptions.getOptions(mStackSupervisor)
10924                : null;
10925        if (activityOptions == null
10926                || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
10927                || activityOptions.getCustomInPlaceResId() == 0) {
10928            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10929                    "with valid animation");
10930        }
10931        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10932        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10933                activityOptions.getCustomInPlaceResId());
10934        mWindowManager.executeAppTransition();
10935    }
10936
10937    @Override
10938    public void removeStack(int stackId) {
10939        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
10940        synchronized (this) {
10941            final long ident = Binder.clearCallingIdentity();
10942            try {
10943                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10944                if (stack == null) {
10945                    Slog.w(TAG, "removeStack: No stack with id=" + stackId);
10946                    return;
10947                }
10948                if (!stack.isActivityTypeStandardOrUndefined()) {
10949                    throw new IllegalArgumentException(
10950                            "Removing non-standard stack is not allowed.");
10951                }
10952                mStackSupervisor.removeStack(stack);
10953            } finally {
10954                Binder.restoreCallingIdentity(ident);
10955            }
10956        }
10957    }
10958
10959    /**
10960     * Removes stacks in the input windowing modes from the system if they are of activity type
10961     * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
10962     */
10963    @Override
10964    public void removeStacksInWindowingModes(int[] windowingModes) {
10965        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10966                "removeStacksInWindowingModes()");
10967        synchronized (this) {
10968            final long ident = Binder.clearCallingIdentity();
10969            try {
10970                mStackSupervisor.removeStacksInWindowingModes(windowingModes);
10971            } finally {
10972                Binder.restoreCallingIdentity(ident);
10973            }
10974        }
10975    }
10976
10977    @Override
10978    public void removeStacksWithActivityTypes(int[] activityTypes) {
10979        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10980                "removeStacksWithActivityTypes()");
10981        synchronized (this) {
10982            final long ident = Binder.clearCallingIdentity();
10983            try {
10984                mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
10985            } finally {
10986                Binder.restoreCallingIdentity(ident);
10987            }
10988        }
10989    }
10990
10991    @Override
10992    public void moveStackToDisplay(int stackId, int displayId) {
10993        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10994
10995        synchronized (this) {
10996            final long ident = Binder.clearCallingIdentity();
10997            try {
10998                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10999                        + " to displayId=" + displayId);
11000                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
11001            } finally {
11002                Binder.restoreCallingIdentity(ident);
11003            }
11004        }
11005    }
11006
11007    @Override
11008    public boolean removeTask(int taskId) {
11009        enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
11010        synchronized (this) {
11011            final long ident = Binder.clearCallingIdentity();
11012            try {
11013                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
11014                        "remove-task");
11015            } finally {
11016                Binder.restoreCallingIdentity(ident);
11017            }
11018        }
11019    }
11020
11021    /**
11022     * TODO: Add mController hook
11023     */
11024    @Override
11025    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
11026        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
11027
11028        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
11029        synchronized(this) {
11030            moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
11031                    false /* fromRecents */);
11032        }
11033    }
11034
11035    void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
11036            boolean fromRecents) {
11037
11038        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
11039                Binder.getCallingUid(), -1, -1, "Task to front")) {
11040            SafeActivityOptions.abort(options);
11041            return;
11042        }
11043        final long origId = Binder.clearCallingIdentity();
11044        try {
11045            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11046            if (task == null) {
11047                Slog.d(TAG, "Could not find task for id: "+ taskId);
11048                return;
11049            }
11050            if (mLockTaskController.isLockTaskModeViolation(task)) {
11051                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
11052                return;
11053            }
11054            ActivityOptions realOptions = options != null
11055                    ? options.getOptions(mStackSupervisor)
11056                    : null;
11057            mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
11058                    false /* forceNonResizable */);
11059
11060            final ActivityRecord topActivity = task.getTopActivity();
11061            if (topActivity != null) {
11062
11063                // We are reshowing a task, use a starting window to hide the initial draw delay
11064                // so the transition can start earlier.
11065                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
11066                        true /* taskSwitch */, fromRecents);
11067            }
11068        } finally {
11069            Binder.restoreCallingIdentity(origId);
11070        }
11071        SafeActivityOptions.abort(options);
11072    }
11073
11074    /**
11075     * Attempts to move a task backwards in z-order (the order of activities within the task is
11076     * unchanged).
11077     *
11078     * There are several possible results of this call:
11079     * - if the task is locked, then we will show the lock toast
11080     * - if there is a task behind the provided task, then that task is made visible and resumed as
11081     *   this task is moved to the back
11082     * - otherwise, if there are no other tasks in the stack:
11083     *     - if this task is in the pinned stack, then we remove the stack completely, which will
11084     *       have the effect of moving the task to the top or bottom of the fullscreen stack
11085     *       (depending on whether it is visible)
11086     *     - otherwise, we simply return home and hide this task
11087     *
11088     * @param token A reference to the activity we wish to move
11089     * @param nonRoot If false then this only works if the activity is the root
11090     *                of a task; if true it will work for any activity in a task.
11091     * @return Returns true if the move completed, false if not.
11092     */
11093    @Override
11094    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
11095        enforceNotIsolatedCaller("moveActivityTaskToBack");
11096        synchronized(this) {
11097            final long origId = Binder.clearCallingIdentity();
11098            try {
11099                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
11100                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11101                if (task != null) {
11102                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
11103                }
11104            } finally {
11105                Binder.restoreCallingIdentity(origId);
11106            }
11107        }
11108        return false;
11109    }
11110
11111    @Override
11112    public void moveTaskBackwards(int task) {
11113        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
11114                "moveTaskBackwards()");
11115
11116        synchronized(this) {
11117            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
11118                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
11119                return;
11120            }
11121            final long origId = Binder.clearCallingIdentity();
11122            moveTaskBackwardsLocked(task);
11123            Binder.restoreCallingIdentity(origId);
11124        }
11125    }
11126
11127    private final void moveTaskBackwardsLocked(int task) {
11128        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
11129    }
11130
11131    @Override
11132    public int createStackOnDisplay(int displayId) throws RemoteException {
11133        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
11134        synchronized (this) {
11135            final ActivityDisplay display =
11136                    mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
11137            if (display == null) {
11138                return INVALID_STACK_ID;
11139            }
11140            // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
11141            final ActivityStack stack = display.createStack(
11142                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
11143                    ON_TOP);
11144            return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
11145        }
11146    }
11147
11148    @Override
11149    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
11150        synchronized (this) {
11151            final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
11152            if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
11153                return stack.mDisplayId;
11154            }
11155            return DEFAULT_DISPLAY;
11156        }
11157    }
11158
11159    @Override
11160    public void exitFreeformMode(IBinder token) throws RemoteException {
11161        synchronized (this) {
11162            long ident = Binder.clearCallingIdentity();
11163            try {
11164                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11165                if (r == null) {
11166                    throw new IllegalArgumentException(
11167                            "exitFreeformMode: No activity record matching token=" + token);
11168                }
11169
11170                final ActivityStack stack = r.getStack();
11171                if (stack == null || !stack.inFreeformWindowingMode()) {
11172                    throw new IllegalStateException(
11173                            "exitFreeformMode: You can only go fullscreen from freeform.");
11174                }
11175
11176                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11177            } finally {
11178                Binder.restoreCallingIdentity(ident);
11179            }
11180        }
11181    }
11182
11183    @Override
11184    public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
11185        if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
11186            setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
11187                    toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
11188            return;
11189        }
11190        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
11191        synchronized (this) {
11192            final long ident = Binder.clearCallingIdentity();
11193            try {
11194                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11195                if (task == null) {
11196                    Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
11197                    return;
11198                }
11199
11200                if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
11201                        + " to windowingMode=" + windowingMode + " toTop=" + toTop);
11202
11203                if (!task.isActivityTypeStandardOrUndefined()) {
11204                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11205                            + " non-standard task " + taskId + " to windowing mode="
11206                            + windowingMode);
11207                }
11208
11209                final ActivityStack stack = task.getStack();
11210                if (toTop) {
11211                    stack.moveToFront("setTaskWindowingMode", task);
11212                }
11213                stack.setWindowingMode(windowingMode);
11214            } finally {
11215                Binder.restoreCallingIdentity(ident);
11216            }
11217        }
11218    }
11219
11220    /**
11221     * Moves the specified task to the primary-split-screen stack.
11222     *
11223     * @param taskId Id of task to move.
11224     * @param createMode The mode the primary split screen stack should be created in if it doesn't
11225     *                   exist already. See
11226     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
11227     *                   and
11228     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
11229     * @param toTop If the task and stack should be moved to the top.
11230     * @param animate Whether we should play an animation for the moving the task.
11231     * @param initialBounds If the primary stack gets created, it will use these bounds for the
11232     *                      stack. Pass {@code null} to use default bounds.
11233     * @param showRecents If the recents activity should be shown on the other side of the task
11234     *                    going into split-screen mode.
11235     */
11236    @Override
11237    public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
11238            boolean animate, Rect initialBounds, boolean showRecents) {
11239        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11240                "setTaskWindowingModeSplitScreenPrimary()");
11241        synchronized (this) {
11242            long ident = Binder.clearCallingIdentity();
11243            try {
11244                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11245                if (task == null) {
11246                    Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
11247                    return false;
11248                }
11249                if (DEBUG_STACK) Slog.d(TAG_STACK,
11250                        "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
11251                        + " to createMode=" + createMode + " toTop=" + toTop);
11252                if (!task.isActivityTypeStandardOrUndefined()) {
11253                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11254                            + " non-standard task " + taskId + " to split-screen windowing mode");
11255                }
11256
11257                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
11258                final int windowingMode = task.getWindowingMode();
11259                final ActivityStack stack = task.getStack();
11260                if (toTop) {
11261                    stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
11262                }
11263                stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
11264                        false /* enteringSplitScreenMode */);
11265                return windowingMode != task.getWindowingMode();
11266            } finally {
11267                Binder.restoreCallingIdentity(ident);
11268            }
11269        }
11270    }
11271
11272    @Override
11273    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
11274        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
11275        synchronized (this) {
11276            long ident = Binder.clearCallingIdentity();
11277            try {
11278                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11279                if (task == null) {
11280                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
11281                    return;
11282                }
11283
11284                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
11285                        + " to stackId=" + stackId + " toTop=" + toTop);
11286
11287                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11288                if (stack == null) {
11289                    throw new IllegalStateException(
11290                            "moveTaskToStack: No stack for stackId=" + stackId);
11291                }
11292                if (!stack.isActivityTypeStandardOrUndefined()) {
11293                    throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
11294                            + taskId + " to stack " + stackId);
11295                }
11296                if (stack.inSplitScreenPrimaryWindowingMode()) {
11297                    mWindowManager.setDockedStackCreateState(
11298                            SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
11299                }
11300                task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
11301                        "moveTaskToStack");
11302            } finally {
11303                Binder.restoreCallingIdentity(ident);
11304            }
11305        }
11306    }
11307
11308    /**
11309     * Dismisses split-screen multi-window mode.
11310     * @param toTop If true the current primary split-screen stack will be placed or left on top.
11311     */
11312    @Override
11313    public void dismissSplitScreenMode(boolean toTop) {
11314        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
11315        final long ident = Binder.clearCallingIdentity();
11316        try {
11317            synchronized (this) {
11318                final ActivityStack stack =
11319                        mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
11320                if (stack == null) {
11321                    Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
11322                    return;
11323                }
11324
11325                if (toTop) {
11326                    // Caller wants the current split-screen primary stack to be the top stack after
11327                    // it goes fullscreen, so move it to the front.
11328                    stack.moveToFront("dismissSplitScreenMode");
11329                } else if (mStackSupervisor.isFocusedStack(stack)) {
11330                    // In this case the current split-screen primary stack shouldn't be the top
11331                    // stack after it goes fullscreen, but it current has focus, so we move the
11332                    // focus to the top-most split-screen secondary stack next to it.
11333                    final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
11334                            WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
11335                    if (otherStack != null) {
11336                        otherStack.moveToFront("dismissSplitScreenMode_other");
11337                    }
11338                }
11339
11340                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11341            }
11342        } finally {
11343            Binder.restoreCallingIdentity(ident);
11344        }
11345    }
11346
11347    /**
11348     * Dismisses Pip
11349     * @param animate True if the dismissal should be animated.
11350     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
11351     *                          default animation duration should be used.
11352     */
11353    @Override
11354    public void dismissPip(boolean animate, int animationDuration) {
11355        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
11356        final long ident = Binder.clearCallingIdentity();
11357        try {
11358            synchronized (this) {
11359                final PinnedActivityStack stack =
11360                        mStackSupervisor.getDefaultDisplay().getPinnedStack();
11361                if (stack == null) {
11362                    Slog.w(TAG, "dismissPip: pinned stack not found.");
11363                    return;
11364                }
11365                if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11366                    throw new IllegalArgumentException("Stack: " + stack
11367                            + " doesn't support animated resize.");
11368                }
11369                if (animate) {
11370                    stack.animateResizePinnedStack(null /* sourceHintBounds */,
11371                            null /* destBounds */, animationDuration, false /* fromFullscreen */);
11372                } else {
11373                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
11374                }
11375            }
11376        } finally {
11377            Binder.restoreCallingIdentity(ident);
11378        }
11379    }
11380
11381    /**
11382     * Moves the top activity in the input stackId to the pinned stack.
11383     *
11384     * @param stackId Id of stack to move the top activity to pinned stack.
11385     * @param bounds Bounds to use for pinned stack.
11386     *
11387     * @return True if the top activity of the input stack was successfully moved to the pinned
11388     *          stack.
11389     */
11390    @Override
11391    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
11392        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11393                "moveTopActivityToPinnedStack()");
11394        synchronized (this) {
11395            if (!mSupportsPictureInPicture) {
11396                throw new IllegalStateException("moveTopActivityToPinnedStack:"
11397                        + "Device doesn't support picture-in-picture mode");
11398            }
11399
11400            long ident = Binder.clearCallingIdentity();
11401            try {
11402                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
11403            } finally {
11404                Binder.restoreCallingIdentity(ident);
11405            }
11406        }
11407    }
11408
11409    @Override
11410    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
11411            boolean preserveWindows, boolean animate, int animationDuration) {
11412        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
11413        long ident = Binder.clearCallingIdentity();
11414        try {
11415            synchronized (this) {
11416                if (animate) {
11417                    final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
11418                    if (stack == null) {
11419                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11420                        return;
11421                    }
11422                    if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11423                        throw new IllegalArgumentException("Stack: " + stackId
11424                                + " doesn't support animated resize.");
11425                    }
11426                    stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
11427                            animationDuration, false /* fromFullscreen */);
11428                } else {
11429                    final ActivityStack stack = mStackSupervisor.getStack(stackId);
11430                    if (stack == null) {
11431                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11432                        return;
11433                    }
11434                    mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
11435                            null /* tempTaskInsetBounds */, preserveWindows,
11436                            allowResizeInDockedMode, !DEFER_RESUME);
11437                }
11438            }
11439        } finally {
11440            Binder.restoreCallingIdentity(ident);
11441        }
11442    }
11443
11444    @Override
11445    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
11446            Rect tempDockedTaskInsetBounds,
11447            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
11448        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
11449        long ident = Binder.clearCallingIdentity();
11450        try {
11451            synchronized (this) {
11452                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
11453                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
11454                        PRESERVE_WINDOWS);
11455            }
11456        } finally {
11457            Binder.restoreCallingIdentity(ident);
11458        }
11459    }
11460
11461    @Override
11462    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
11463        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
11464        final long ident = Binder.clearCallingIdentity();
11465        try {
11466            synchronized (this) {
11467                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
11468            }
11469        } finally {
11470            Binder.restoreCallingIdentity(ident);
11471        }
11472    }
11473
11474    /**
11475     * Try to place task to provided position. The final position might be different depending on
11476     * current user and stacks state. The task will be moved to target stack if it's currently in
11477     * different stack.
11478     */
11479    @Override
11480    public void positionTaskInStack(int taskId, int stackId, int position) {
11481        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
11482        synchronized (this) {
11483            long ident = Binder.clearCallingIdentity();
11484            try {
11485                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
11486                        + taskId + " in stackId=" + stackId + " at position=" + position);
11487                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11488                if (task == null) {
11489                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
11490                            + taskId);
11491                }
11492
11493                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11494
11495                if (stack == null) {
11496                    throw new IllegalArgumentException("positionTaskInStack: no stack for id="
11497                            + stackId);
11498                }
11499                if (!stack.isActivityTypeStandardOrUndefined()) {
11500                    throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
11501                            + " the position of task " + taskId + " in/to non-standard stack");
11502                }
11503
11504                // TODO: Have the callers of this API call a separate reparent method if that is
11505                // what they intended to do vs. having this method also do reparenting.
11506                if (task.getStack() == stack) {
11507                    // Change position in current stack.
11508                    stack.positionChildAt(task, position);
11509                } else {
11510                    // Reparent to new stack.
11511                    task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
11512                            !DEFER_RESUME, "positionTaskInStack");
11513                }
11514            } finally {
11515                Binder.restoreCallingIdentity(ident);
11516            }
11517        }
11518    }
11519
11520    @Override
11521    public List<StackInfo> getAllStackInfos() {
11522        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
11523        long ident = Binder.clearCallingIdentity();
11524        try {
11525            synchronized (this) {
11526                return mStackSupervisor.getAllStackInfosLocked();
11527            }
11528        } finally {
11529            Binder.restoreCallingIdentity(ident);
11530        }
11531    }
11532
11533    @Override
11534    public StackInfo getStackInfo(int windowingMode, int activityType) {
11535        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
11536        long ident = Binder.clearCallingIdentity();
11537        try {
11538            synchronized (this) {
11539                return mStackSupervisor.getStackInfo(windowingMode, activityType);
11540            }
11541        } finally {
11542            Binder.restoreCallingIdentity(ident);
11543        }
11544    }
11545
11546    @Override
11547    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
11548        synchronized(this) {
11549            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
11550        }
11551    }
11552
11553    @Override
11554    public void updateDeviceOwner(String packageName) {
11555        final int callingUid = Binder.getCallingUid();
11556        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11557            throw new SecurityException("updateDeviceOwner called from non-system process");
11558        }
11559        synchronized (this) {
11560            mDeviceOwnerName = packageName;
11561        }
11562    }
11563
11564    @Override
11565    public void updateLockTaskPackages(int userId, String[] packages) {
11566        final int callingUid = Binder.getCallingUid();
11567        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11568            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11569                    "updateLockTaskPackages()");
11570        }
11571        synchronized (this) {
11572            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
11573                    Arrays.toString(packages));
11574            mLockTaskController.updateLockTaskPackages(userId, packages);
11575        }
11576    }
11577
11578    @Override
11579    public void updateLockTaskFeatures(int userId, int flags) {
11580        final int callingUid = Binder.getCallingUid();
11581        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11582            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11583                    "updateLockTaskFeatures()");
11584        }
11585        synchronized (this) {
11586            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
11587                    Integer.toHexString(flags));
11588            mLockTaskController.updateLockTaskFeatures(userId, flags);
11589        }
11590    }
11591
11592    private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
11593        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
11594        if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
11595            return;
11596        }
11597
11598        final ActivityStack stack = mStackSupervisor.getFocusedStack();
11599        if (stack == null || task != stack.topTask()) {
11600            throw new IllegalArgumentException("Invalid task, not in foreground");
11601        }
11602
11603        // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
11604        // system or a specific app.
11605        // * System-initiated requests will only start the pinned mode (screen pinning)
11606        // * App-initiated requests
11607        //   - will put the device in fully locked mode (LockTask), if the app is whitelisted
11608        //   - will start the pinned mode, otherwise
11609        final int callingUid = Binder.getCallingUid();
11610        long ident = Binder.clearCallingIdentity();
11611        try {
11612            // When a task is locked, dismiss the pinned stack if it exists
11613            mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
11614
11615            mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
11616        } finally {
11617            Binder.restoreCallingIdentity(ident);
11618        }
11619    }
11620
11621    @Override
11622    public void startLockTaskModeByToken(IBinder token) {
11623        synchronized (this) {
11624            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11625            if (r == null) {
11626                return;
11627            }
11628            startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
11629        }
11630    }
11631
11632    @Override
11633    public void startSystemLockTaskMode(int taskId) throws RemoteException {
11634        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11635        // This makes inner call to look as if it was initiated by system.
11636        long ident = Binder.clearCallingIdentity();
11637        try {
11638            synchronized (this) {
11639                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11640
11641                // When starting lock task mode the stack must be in front and focused
11642                task.getStack().moveToFront("startSystemLockTaskMode");
11643                startLockTaskModeLocked(task, true /* isSystemCaller */);
11644            }
11645        } finally {
11646            Binder.restoreCallingIdentity(ident);
11647        }
11648    }
11649
11650    @Override
11651    public void stopLockTaskModeByToken(IBinder token) {
11652        synchronized (this) {
11653            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11654            if (r == null) {
11655                return;
11656            }
11657            stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
11658        }
11659    }
11660
11661    /**
11662     * This API should be called by SystemUI only when user perform certain action to dismiss
11663     * lock task mode. We should only dismiss pinned lock task mode in this case.
11664     */
11665    @Override
11666    public void stopSystemLockTaskMode() throws RemoteException {
11667        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
11668        stopLockTaskModeInternal(null, true /* isSystemCaller */);
11669    }
11670
11671    private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
11672        final int callingUid = Binder.getCallingUid();
11673        long ident = Binder.clearCallingIdentity();
11674        try {
11675            synchronized (this) {
11676                mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
11677            }
11678            // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
11679            // task and jumping straight into a call in the case of emergency call back.
11680            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11681            if (tm != null) {
11682                tm.showInCallScreen(false);
11683            }
11684        } finally {
11685            Binder.restoreCallingIdentity(ident);
11686        }
11687    }
11688
11689    @Override
11690    public boolean isInLockTaskMode() {
11691        return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
11692    }
11693
11694    @Override
11695    public int getLockTaskModeState() {
11696        synchronized (this) {
11697            return mLockTaskController.getLockTaskModeState();
11698        }
11699    }
11700
11701    @Override
11702    public void showLockTaskEscapeMessage(IBinder token) {
11703        synchronized (this) {
11704            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11705            if (r == null) {
11706                return;
11707            }
11708            mLockTaskController.showLockTaskToast();
11709        }
11710    }
11711
11712    @Override
11713    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11714            throws RemoteException {
11715        synchronized (this) {
11716            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11717            if (r == null) {
11718                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11719                        + token);
11720                return;
11721            }
11722            final long origId = Binder.clearCallingIdentity();
11723            try {
11724                r.setDisablePreviewScreenshots(disable);
11725            } finally {
11726                Binder.restoreCallingIdentity(origId);
11727            }
11728        }
11729    }
11730
11731    // =========================================================
11732    // CONTENT PROVIDERS
11733    // =========================================================
11734
11735    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11736        List<ProviderInfo> providers = null;
11737        try {
11738            providers = AppGlobals.getPackageManager()
11739                    .queryContentProviders(app.processName, app.uid,
11740                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11741                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11742                    .getList();
11743        } catch (RemoteException ex) {
11744        }
11745        if (DEBUG_MU) Slog.v(TAG_MU,
11746                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11747        int userId = app.userId;
11748        if (providers != null) {
11749            int N = providers.size();
11750            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11751            for (int i=0; i<N; i++) {
11752                // TODO: keep logic in sync with installEncryptionUnawareProviders
11753                ProviderInfo cpi =
11754                    (ProviderInfo)providers.get(i);
11755                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11756                        cpi.name, cpi.flags);
11757                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11758                    // This is a singleton provider, but a user besides the
11759                    // default user is asking to initialize a process it runs
11760                    // in...  well, no, it doesn't actually run in this process,
11761                    // it runs in the process of the default user.  Get rid of it.
11762                    providers.remove(i);
11763                    N--;
11764                    i--;
11765                    continue;
11766                }
11767
11768                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11769                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11770                if (cpr == null) {
11771                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11772                    mProviderMap.putProviderByClass(comp, cpr);
11773                }
11774                if (DEBUG_MU) Slog.v(TAG_MU,
11775                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11776                app.pubProviders.put(cpi.name, cpr);
11777                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11778                    // Don't add this if it is a platform component that is marked
11779                    // to run in multiple processes, because this is actually
11780                    // part of the framework so doesn't make sense to track as a
11781                    // separate apk in the process.
11782                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11783                            mProcessStats);
11784                }
11785                notifyPackageUse(cpi.applicationInfo.packageName,
11786                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11787            }
11788        }
11789        return providers;
11790    }
11791
11792    /**
11793     * Check if the calling UID has a possible chance at accessing the provider
11794     * at the given authority and user.
11795     */
11796    public String checkContentProviderAccess(String authority, int userId) {
11797        if (userId == UserHandle.USER_ALL) {
11798            mContext.enforceCallingOrSelfPermission(
11799                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11800            userId = UserHandle.getCallingUserId();
11801        }
11802
11803        ProviderInfo cpi = null;
11804        try {
11805            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11806                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11807                            | PackageManager.MATCH_DISABLED_COMPONENTS
11808                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11809                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11810                    userId);
11811        } catch (RemoteException ignored) {
11812        }
11813        if (cpi == null) {
11814            return "Failed to find provider " + authority + " for user " + userId
11815                    + "; expected to find a valid ContentProvider for this authority";
11816        }
11817
11818        ProcessRecord r = null;
11819        synchronized (mPidsSelfLocked) {
11820            r = mPidsSelfLocked.get(Binder.getCallingPid());
11821        }
11822        if (r == null) {
11823            return "Failed to find PID " + Binder.getCallingPid();
11824        }
11825
11826        synchronized (this) {
11827            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11828        }
11829    }
11830
11831    /**
11832     * Check if {@link ProcessRecord} has a possible chance at accessing the
11833     * given {@link ProviderInfo}. Final permission checking is always done
11834     * in {@link ContentProvider}.
11835     */
11836    private final String checkContentProviderPermissionLocked(
11837            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11838        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11839        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11840        boolean checkedGrants = false;
11841        if (checkUser) {
11842            // Looking for cross-user grants before enforcing the typical cross-users permissions
11843            int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
11844            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11845                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11846                    return null;
11847                }
11848                checkedGrants = true;
11849            }
11850            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11851                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11852            if (userId != tmpTargetUserId) {
11853                // When we actually went to determine the final targer user ID, this ended
11854                // up different than our initial check for the authority.  This is because
11855                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11856                // SELF.  So we need to re-check the grants again.
11857                checkedGrants = false;
11858            }
11859        }
11860        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11861                cpi.applicationInfo.uid, cpi.exported)
11862                == PackageManager.PERMISSION_GRANTED) {
11863            return null;
11864        }
11865        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11866                cpi.applicationInfo.uid, cpi.exported)
11867                == PackageManager.PERMISSION_GRANTED) {
11868            return null;
11869        }
11870
11871        PathPermission[] pps = cpi.pathPermissions;
11872        if (pps != null) {
11873            int i = pps.length;
11874            while (i > 0) {
11875                i--;
11876                PathPermission pp = pps[i];
11877                String pprperm = pp.getReadPermission();
11878                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11879                        cpi.applicationInfo.uid, cpi.exported)
11880                        == PackageManager.PERMISSION_GRANTED) {
11881                    return null;
11882                }
11883                String ppwperm = pp.getWritePermission();
11884                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11885                        cpi.applicationInfo.uid, cpi.exported)
11886                        == PackageManager.PERMISSION_GRANTED) {
11887                    return null;
11888                }
11889            }
11890        }
11891        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11892            return null;
11893        }
11894
11895        final String suffix;
11896        if (!cpi.exported) {
11897            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11898        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11899            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11900        } else {
11901            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11902        }
11903        final String msg = "Permission Denial: opening provider " + cpi.name
11904                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11905                + ", uid=" + callingUid + ")" + suffix;
11906        Slog.w(TAG, msg);
11907        return msg;
11908    }
11909
11910    /**
11911     * Returns if the ContentProvider has granted a uri to callingUid
11912     */
11913    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11914        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11915        if (perms != null) {
11916            for (int i=perms.size()-1; i>=0; i--) {
11917                GrantUri grantUri = perms.keyAt(i);
11918                if (grantUri.sourceUserId == userId || !checkUser) {
11919                    if (matchesProvider(grantUri.uri, cpi)) {
11920                        return true;
11921                    }
11922                }
11923            }
11924        }
11925        return false;
11926    }
11927
11928    /**
11929     * Returns true if the uri authority is one of the authorities specified in the provider.
11930     */
11931    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11932        String uriAuth = uri.getAuthority();
11933        String cpiAuth = cpi.authority;
11934        if (cpiAuth.indexOf(';') == -1) {
11935            return cpiAuth.equals(uriAuth);
11936        }
11937        String[] cpiAuths = cpiAuth.split(";");
11938        int length = cpiAuths.length;
11939        for (int i = 0; i < length; i++) {
11940            if (cpiAuths[i].equals(uriAuth)) return true;
11941        }
11942        return false;
11943    }
11944
11945    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11946            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11947        if (r != null) {
11948            for (int i=0; i<r.conProviders.size(); i++) {
11949                ContentProviderConnection conn = r.conProviders.get(i);
11950                if (conn.provider == cpr) {
11951                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11952                            "Adding provider requested by "
11953                            + r.processName + " from process "
11954                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11955                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11956                    if (stable) {
11957                        conn.stableCount++;
11958                        conn.numStableIncs++;
11959                    } else {
11960                        conn.unstableCount++;
11961                        conn.numUnstableIncs++;
11962                    }
11963                    return conn;
11964                }
11965            }
11966            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11967            if (stable) {
11968                conn.stableCount = 1;
11969                conn.numStableIncs = 1;
11970            } else {
11971                conn.unstableCount = 1;
11972                conn.numUnstableIncs = 1;
11973            }
11974            cpr.connections.add(conn);
11975            r.conProviders.add(conn);
11976            startAssociationLocked(r.uid, r.processName, r.curProcState,
11977                    cpr.uid, cpr.name, cpr.info.processName);
11978            return conn;
11979        }
11980        cpr.addExternalProcessHandleLocked(externalProcessToken);
11981        return null;
11982    }
11983
11984    boolean decProviderCountLocked(ContentProviderConnection conn,
11985            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11986        if (conn != null) {
11987            cpr = conn.provider;
11988            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11989                    "Removing provider requested by "
11990                    + conn.client.processName + " from process "
11991                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11992                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11993            if (stable) {
11994                conn.stableCount--;
11995            } else {
11996                conn.unstableCount--;
11997            }
11998            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11999                cpr.connections.remove(conn);
12000                conn.client.conProviders.remove(conn);
12001                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
12002                    // The client is more important than last activity -- note the time this
12003                    // is happening, so we keep the old provider process around a bit as last
12004                    // activity to avoid thrashing it.
12005                    if (cpr.proc != null) {
12006                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
12007                    }
12008                }
12009                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
12010                return true;
12011            }
12012            return false;
12013        }
12014        cpr.removeExternalProcessHandleLocked(externalProcessToken);
12015        return false;
12016    }
12017
12018    private void checkTime(long startTime, String where) {
12019        long now = SystemClock.uptimeMillis();
12020        if ((now-startTime) > 50) {
12021            // If we are taking more than 50ms, log about it.
12022            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
12023        }
12024    }
12025
12026    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
12027            PROC_SPACE_TERM,
12028            PROC_SPACE_TERM|PROC_PARENS,
12029            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
12030    };
12031
12032    private final long[] mProcessStateStatsLongs = new long[1];
12033
12034    private boolean isProcessAliveLocked(ProcessRecord proc) {
12035        if (proc.pid <= 0) {
12036            if (DEBUG_OOM_ADJ) Slog.d(TAG, "Process hasn't started yet: " + proc);
12037            return false;
12038        }
12039        if (proc.procStatFile == null) {
12040            proc.procStatFile = "/proc/" + proc.pid + "/stat";
12041        }
12042        mProcessStateStatsLongs[0] = 0;
12043        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
12044                mProcessStateStatsLongs, null)) {
12045            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
12046            return false;
12047        }
12048        final long state = mProcessStateStatsLongs[0];
12049        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
12050                + (char)state);
12051        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
12052    }
12053
12054    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
12055            String name, IBinder token, boolean stable, int userId) {
12056        ContentProviderRecord cpr;
12057        ContentProviderConnection conn = null;
12058        ProviderInfo cpi = null;
12059
12060        synchronized(this) {
12061            long startTime = SystemClock.uptimeMillis();
12062
12063            ProcessRecord r = null;
12064            if (caller != null) {
12065                r = getRecordForAppLocked(caller);
12066                if (r == null) {
12067                    throw new SecurityException(
12068                            "Unable to find app for caller " + caller
12069                          + " (pid=" + Binder.getCallingPid()
12070                          + ") when getting content provider " + name);
12071                }
12072            }
12073
12074            boolean checkCrossUser = true;
12075
12076            checkTime(startTime, "getContentProviderImpl: getProviderByName");
12077
12078            // First check if this content provider has been published...
12079            cpr = mProviderMap.getProviderByName(name, userId);
12080            // If that didn't work, check if it exists for user 0 and then
12081            // verify that it's a singleton provider before using it.
12082            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
12083                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
12084                if (cpr != null) {
12085                    cpi = cpr.info;
12086                    if (isSingleton(cpi.processName, cpi.applicationInfo,
12087                            cpi.name, cpi.flags)
12088                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
12089                        userId = UserHandle.USER_SYSTEM;
12090                        checkCrossUser = false;
12091                    } else {
12092                        cpr = null;
12093                        cpi = null;
12094                    }
12095                }
12096            }
12097
12098            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
12099            if (providerRunning) {
12100                cpi = cpr.info;
12101                String msg;
12102                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12103                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
12104                        != null) {
12105                    throw new SecurityException(msg);
12106                }
12107                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
12108
12109                if (r != null && cpr.canRunHere(r)) {
12110                    // This provider has been published or is in the process
12111                    // of being published...  but it is also allowed to run
12112                    // in the caller's process, so don't make a connection
12113                    // and just let the caller instantiate its own instance.
12114                    ContentProviderHolder holder = cpr.newHolder(null);
12115                    // don't give caller the provider object, it needs
12116                    // to make its own.
12117                    holder.provider = null;
12118                    return holder;
12119                }
12120                // Don't expose providers between normal apps and instant apps
12121                try {
12122                    if (AppGlobals.getPackageManager()
12123                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
12124                        return null;
12125                    }
12126                } catch (RemoteException e) {
12127                }
12128
12129                final long origId = Binder.clearCallingIdentity();
12130
12131                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
12132
12133                // In this case the provider instance already exists, so we can
12134                // return it right away.
12135                conn = incProviderCountLocked(r, cpr, token, stable);
12136                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
12137                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12138                        // If this is a perceptible app accessing the provider,
12139                        // make sure to count it as being accessed and thus
12140                        // back up on the LRU list.  This is good because
12141                        // content providers are often expensive to start.
12142                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
12143                        updateLruProcessLocked(cpr.proc, false, null);
12144                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
12145                    }
12146                }
12147
12148                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
12149                final int verifiedAdj = cpr.proc.verifiedAdj;
12150                boolean success = updateOomAdjLocked(cpr.proc, true);
12151                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
12152                // if the process has been successfully adjusted.  So to reduce races with
12153                // it, we will check whether the process still exists.  Note that this doesn't
12154                // completely get rid of races with LMK killing the process, but should make
12155                // them much smaller.
12156                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
12157                    success = false;
12158                }
12159                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
12160                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
12161                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
12162                // NOTE: there is still a race here where a signal could be
12163                // pending on the process even though we managed to update its
12164                // adj level.  Not sure what to do about this, but at least
12165                // the race is now smaller.
12166                if (!success) {
12167                    // Uh oh...  it looks like the provider's process
12168                    // has been killed on us.  We need to wait for a new
12169                    // process to be started, and make sure its death
12170                    // doesn't kill our process.
12171                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
12172                            + " is crashing; detaching " + r);
12173                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
12174                    checkTime(startTime, "getContentProviderImpl: before appDied");
12175                    appDiedLocked(cpr.proc);
12176                    checkTime(startTime, "getContentProviderImpl: after appDied");
12177                    if (!lastRef) {
12178                        // This wasn't the last ref our process had on
12179                        // the provider...  we have now been killed, bail.
12180                        return null;
12181                    }
12182                    providerRunning = false;
12183                    conn = null;
12184                } else {
12185                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
12186                }
12187
12188                Binder.restoreCallingIdentity(origId);
12189            }
12190
12191            if (!providerRunning) {
12192                try {
12193                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
12194                    cpi = AppGlobals.getPackageManager().
12195                        resolveContentProvider(name,
12196                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
12197                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
12198                } catch (RemoteException ex) {
12199                }
12200                if (cpi == null) {
12201                    return null;
12202                }
12203                // If the provider is a singleton AND
12204                // (it's a call within the same user || the provider is a
12205                // privileged app)
12206                // Then allow connecting to the singleton provider
12207                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
12208                        cpi.name, cpi.flags)
12209                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
12210                if (singleton) {
12211                    userId = UserHandle.USER_SYSTEM;
12212                }
12213                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
12214                checkTime(startTime, "getContentProviderImpl: got app info for user");
12215
12216                String msg;
12217                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12218                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
12219                        != null) {
12220                    throw new SecurityException(msg);
12221                }
12222                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
12223
12224                if (!mProcessesReady
12225                        && !cpi.processName.equals("system")) {
12226                    // If this content provider does not run in the system
12227                    // process, and the system is not yet ready to run other
12228                    // processes, then fail fast instead of hanging.
12229                    throw new IllegalArgumentException(
12230                            "Attempt to launch content provider before system ready");
12231                }
12232
12233                // If system providers are not installed yet we aggressively crash to avoid
12234                // creating multiple instance of these providers and then bad things happen!
12235                if (!mSystemProvidersInstalled && cpi.applicationInfo.isSystemApp()
12236                        && "system".equals(cpi.processName)) {
12237                    throw new IllegalStateException("Cannot access system provider: '"
12238                            + cpi.authority + "' before system providers are installed!");
12239                }
12240
12241                // Make sure that the user who owns this provider is running.  If not,
12242                // we don't want to allow it to run.
12243                if (!mUserController.isUserRunning(userId, 0)) {
12244                    Slog.w(TAG, "Unable to launch app "
12245                            + cpi.applicationInfo.packageName + "/"
12246                            + cpi.applicationInfo.uid + " for provider "
12247                            + name + ": user " + userId + " is stopped");
12248                    return null;
12249                }
12250
12251                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
12252                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
12253                cpr = mProviderMap.getProviderByClass(comp, userId);
12254                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
12255                final boolean firstClass = cpr == null;
12256                if (firstClass) {
12257                    final long ident = Binder.clearCallingIdentity();
12258
12259                    // If permissions need a review before any of the app components can run,
12260                    // we return no provider and launch a review activity if the calling app
12261                    // is in the foreground.
12262                    if (mPermissionReviewRequired) {
12263                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
12264                            return null;
12265                        }
12266                    }
12267
12268                    try {
12269                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
12270                        ApplicationInfo ai =
12271                            AppGlobals.getPackageManager().
12272                                getApplicationInfo(
12273                                        cpi.applicationInfo.packageName,
12274                                        STOCK_PM_FLAGS, userId);
12275                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
12276                        if (ai == null) {
12277                            Slog.w(TAG, "No package info for content provider "
12278                                    + cpi.name);
12279                            return null;
12280                        }
12281                        ai = getAppInfoForUser(ai, userId);
12282                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
12283                    } catch (RemoteException ex) {
12284                        // pm is in same process, this will never happen.
12285                    } finally {
12286                        Binder.restoreCallingIdentity(ident);
12287                    }
12288                }
12289
12290                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
12291
12292                if (r != null && cpr.canRunHere(r)) {
12293                    // If this is a multiprocess provider, then just return its
12294                    // info and allow the caller to instantiate it.  Only do
12295                    // this if the provider is the same user as the caller's
12296                    // process, or can run as root (so can be in any process).
12297                    return cpr.newHolder(null);
12298                }
12299
12300                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
12301                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
12302                            + cpr.info.name + " callers=" + Debug.getCallers(6));
12303
12304                // This is single process, and our app is now connecting to it.
12305                // See if we are already in the process of launching this
12306                // provider.
12307                final int N = mLaunchingProviders.size();
12308                int i;
12309                for (i = 0; i < N; i++) {
12310                    if (mLaunchingProviders.get(i) == cpr) {
12311                        break;
12312                    }
12313                }
12314
12315                // If the provider is not already being launched, then get it
12316                // started.
12317                if (i >= N) {
12318                    final long origId = Binder.clearCallingIdentity();
12319
12320                    try {
12321                        // Content provider is now in use, its package can't be stopped.
12322                        try {
12323                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
12324                            AppGlobals.getPackageManager().setPackageStoppedState(
12325                                    cpr.appInfo.packageName, false, userId);
12326                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
12327                        } catch (RemoteException e) {
12328                        } catch (IllegalArgumentException e) {
12329                            Slog.w(TAG, "Failed trying to unstop package "
12330                                    + cpr.appInfo.packageName + ": " + e);
12331                        }
12332
12333                        // Use existing process if already started
12334                        checkTime(startTime, "getContentProviderImpl: looking for process record");
12335                        ProcessRecord proc = getProcessRecordLocked(
12336                                cpi.processName, cpr.appInfo.uid, false);
12337                        if (proc != null && proc.thread != null && !proc.killed) {
12338                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
12339                                    "Installing in existing process " + proc);
12340                            if (!proc.pubProviders.containsKey(cpi.name)) {
12341                                checkTime(startTime, "getContentProviderImpl: scheduling install");
12342                                proc.pubProviders.put(cpi.name, cpr);
12343                                try {
12344                                    proc.thread.scheduleInstallProvider(cpi);
12345                                } catch (RemoteException e) {
12346                                }
12347                            }
12348                        } else {
12349                            checkTime(startTime, "getContentProviderImpl: before start process");
12350                            proc = startProcessLocked(cpi.processName,
12351                                    cpr.appInfo, false, 0, "content provider",
12352                                    new ComponentName(cpi.applicationInfo.packageName,
12353                                            cpi.name), false, false, false);
12354                            checkTime(startTime, "getContentProviderImpl: after start process");
12355                            if (proc == null) {
12356                                Slog.w(TAG, "Unable to launch app "
12357                                        + cpi.applicationInfo.packageName + "/"
12358                                        + cpi.applicationInfo.uid + " for provider "
12359                                        + name + ": process is bad");
12360                                return null;
12361                            }
12362                        }
12363                        cpr.launchingApp = proc;
12364                        mLaunchingProviders.add(cpr);
12365                    } finally {
12366                        Binder.restoreCallingIdentity(origId);
12367                    }
12368                }
12369
12370                checkTime(startTime, "getContentProviderImpl: updating data structures");
12371
12372                // Make sure the provider is published (the same provider class
12373                // may be published under multiple names).
12374                if (firstClass) {
12375                    mProviderMap.putProviderByClass(comp, cpr);
12376                }
12377
12378                mProviderMap.putProviderByName(name, cpr);
12379                conn = incProviderCountLocked(r, cpr, token, stable);
12380                if (conn != null) {
12381                    conn.waiting = true;
12382                }
12383            }
12384            checkTime(startTime, "getContentProviderImpl: done!");
12385
12386            grantEphemeralAccessLocked(userId, null /*intent*/,
12387                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
12388        }
12389
12390        // Wait for the provider to be published...
12391        synchronized (cpr) {
12392            while (cpr.provider == null) {
12393                if (cpr.launchingApp == null) {
12394                    Slog.w(TAG, "Unable to launch app "
12395                            + cpi.applicationInfo.packageName + "/"
12396                            + cpi.applicationInfo.uid + " for provider "
12397                            + name + ": launching app became null");
12398                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
12399                            UserHandle.getUserId(cpi.applicationInfo.uid),
12400                            cpi.applicationInfo.packageName,
12401                            cpi.applicationInfo.uid, name);
12402                    return null;
12403                }
12404                try {
12405                    if (DEBUG_MU) Slog.v(TAG_MU,
12406                            "Waiting to start provider " + cpr
12407                            + " launchingApp=" + cpr.launchingApp);
12408                    if (conn != null) {
12409                        conn.waiting = true;
12410                    }
12411                    cpr.wait();
12412                } catch (InterruptedException ex) {
12413                } finally {
12414                    if (conn != null) {
12415                        conn.waiting = false;
12416                    }
12417                }
12418            }
12419        }
12420        return cpr != null ? cpr.newHolder(conn) : null;
12421    }
12422
12423    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
12424            ProcessRecord r, final int userId) {
12425        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
12426                cpi.packageName, userId)) {
12427
12428            final boolean callerForeground = r == null || r.setSchedGroup
12429                    != ProcessList.SCHED_GROUP_BACKGROUND;
12430
12431            // Show a permission review UI only for starting from a foreground app
12432            if (!callerForeground) {
12433                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
12434                        + cpi.packageName + " requires a permissions review");
12435                return false;
12436            }
12437
12438            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
12439            intent.addFlags(FLAG_ACTIVITY_NEW_TASK
12440                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
12441            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
12442
12443            if (DEBUG_PERMISSIONS_REVIEW) {
12444                Slog.i(TAG, "u" + userId + " Launching permission review "
12445                        + "for package " + cpi.packageName);
12446            }
12447
12448            final UserHandle userHandle = new UserHandle(userId);
12449            mHandler.post(new Runnable() {
12450                @Override
12451                public void run() {
12452                    mContext.startActivityAsUser(intent, userHandle);
12453                }
12454            });
12455
12456            return false;
12457        }
12458
12459        return true;
12460    }
12461
12462    /**
12463     * Returns the PackageManager. Used by classes hosted by {@link ActivityManagerService}. The
12464     * PackageManager could be unavailable at construction time and therefore needs to be accessed
12465     * on demand.
12466     */
12467    IPackageManager getPackageManager() {
12468        return AppGlobals.getPackageManager();
12469    }
12470
12471    ActivityStartController getActivityStartController() {
12472        return mActivityStartController;
12473    }
12474
12475    LockTaskController getLockTaskController() {
12476        return mLockTaskController;
12477    }
12478
12479    ClientLifecycleManager getLifecycleManager() {
12480        return mLifecycleManager;
12481    }
12482
12483    PackageManagerInternal getPackageManagerInternalLocked() {
12484        if (mPackageManagerInt == null) {
12485            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
12486        }
12487        return mPackageManagerInt;
12488    }
12489
12490    @Override
12491    public final ContentProviderHolder getContentProvider(
12492            IApplicationThread caller, String name, int userId, boolean stable) {
12493        enforceNotIsolatedCaller("getContentProvider");
12494        if (caller == null) {
12495            String msg = "null IApplicationThread when getting content provider "
12496                    + name;
12497            Slog.w(TAG, msg);
12498            throw new SecurityException(msg);
12499        }
12500        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
12501        // with cross-user grant.
12502        return getContentProviderImpl(caller, name, null, stable, userId);
12503    }
12504
12505    public ContentProviderHolder getContentProviderExternal(
12506            String name, int userId, IBinder token) {
12507        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12508            "Do not have permission in call getContentProviderExternal()");
12509        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12510                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
12511        return getContentProviderExternalUnchecked(name, token, userId);
12512    }
12513
12514    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
12515            IBinder token, int userId) {
12516        return getContentProviderImpl(null, name, token, true, userId);
12517    }
12518
12519    /**
12520     * Drop a content provider from a ProcessRecord's bookkeeping
12521     */
12522    public void removeContentProvider(IBinder connection, boolean stable) {
12523        enforceNotIsolatedCaller("removeContentProvider");
12524        long ident = Binder.clearCallingIdentity();
12525        try {
12526            synchronized (this) {
12527                ContentProviderConnection conn;
12528                try {
12529                    conn = (ContentProviderConnection)connection;
12530                } catch (ClassCastException e) {
12531                    String msg ="removeContentProvider: " + connection
12532                            + " not a ContentProviderConnection";
12533                    Slog.w(TAG, msg);
12534                    throw new IllegalArgumentException(msg);
12535                }
12536                if (conn == null) {
12537                    throw new NullPointerException("connection is null");
12538                }
12539                if (decProviderCountLocked(conn, null, null, stable)) {
12540                    updateOomAdjLocked();
12541                }
12542            }
12543        } finally {
12544            Binder.restoreCallingIdentity(ident);
12545        }
12546    }
12547
12548    public void removeContentProviderExternal(String name, IBinder token) {
12549        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12550            "Do not have permission in call removeContentProviderExternal()");
12551        int userId = UserHandle.getCallingUserId();
12552        long ident = Binder.clearCallingIdentity();
12553        try {
12554            removeContentProviderExternalUnchecked(name, token, userId);
12555        } finally {
12556            Binder.restoreCallingIdentity(ident);
12557        }
12558    }
12559
12560    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
12561        synchronized (this) {
12562            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
12563            if(cpr == null) {
12564                //remove from mProvidersByClass
12565                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
12566                return;
12567            }
12568
12569            //update content provider record entry info
12570            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
12571            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
12572            if (localCpr.hasExternalProcessHandles()) {
12573                if (localCpr.removeExternalProcessHandleLocked(token)) {
12574                    updateOomAdjLocked();
12575                } else {
12576                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
12577                            + " with no external reference for token: "
12578                            + token + ".");
12579                }
12580            } else {
12581                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
12582                        + " with no external references.");
12583            }
12584        }
12585    }
12586
12587    public final void publishContentProviders(IApplicationThread caller,
12588            List<ContentProviderHolder> providers) {
12589        if (providers == null) {
12590            return;
12591        }
12592
12593        enforceNotIsolatedCaller("publishContentProviders");
12594        synchronized (this) {
12595            final ProcessRecord r = getRecordForAppLocked(caller);
12596            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
12597            if (r == null) {
12598                throw new SecurityException(
12599                        "Unable to find app for caller " + caller
12600                      + " (pid=" + Binder.getCallingPid()
12601                      + ") when publishing content providers");
12602            }
12603
12604            final long origId = Binder.clearCallingIdentity();
12605
12606            final int N = providers.size();
12607            for (int i = 0; i < N; i++) {
12608                ContentProviderHolder src = providers.get(i);
12609                if (src == null || src.info == null || src.provider == null) {
12610                    continue;
12611                }
12612                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
12613                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
12614                if (dst != null) {
12615                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
12616                    mProviderMap.putProviderByClass(comp, dst);
12617                    String names[] = dst.info.authority.split(";");
12618                    for (int j = 0; j < names.length; j++) {
12619                        mProviderMap.putProviderByName(names[j], dst);
12620                    }
12621
12622                    int launchingCount = mLaunchingProviders.size();
12623                    int j;
12624                    boolean wasInLaunchingProviders = false;
12625                    for (j = 0; j < launchingCount; j++) {
12626                        if (mLaunchingProviders.get(j) == dst) {
12627                            mLaunchingProviders.remove(j);
12628                            wasInLaunchingProviders = true;
12629                            j--;
12630                            launchingCount--;
12631                        }
12632                    }
12633                    if (wasInLaunchingProviders) {
12634                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12635                    }
12636                    synchronized (dst) {
12637                        dst.provider = src.provider;
12638                        dst.proc = r;
12639                        dst.notifyAll();
12640                    }
12641                    updateOomAdjLocked(r, true);
12642                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12643                            src.info.authority);
12644                }
12645            }
12646
12647            Binder.restoreCallingIdentity(origId);
12648        }
12649    }
12650
12651    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12652        ContentProviderConnection conn;
12653        try {
12654            conn = (ContentProviderConnection)connection;
12655        } catch (ClassCastException e) {
12656            String msg ="refContentProvider: " + connection
12657                    + " not a ContentProviderConnection";
12658            Slog.w(TAG, msg);
12659            throw new IllegalArgumentException(msg);
12660        }
12661        if (conn == null) {
12662            throw new NullPointerException("connection is null");
12663        }
12664
12665        synchronized (this) {
12666            if (stable > 0) {
12667                conn.numStableIncs += stable;
12668            }
12669            stable = conn.stableCount + stable;
12670            if (stable < 0) {
12671                throw new IllegalStateException("stableCount < 0: " + stable);
12672            }
12673
12674            if (unstable > 0) {
12675                conn.numUnstableIncs += unstable;
12676            }
12677            unstable = conn.unstableCount + unstable;
12678            if (unstable < 0) {
12679                throw new IllegalStateException("unstableCount < 0: " + unstable);
12680            }
12681
12682            if ((stable+unstable) <= 0) {
12683                throw new IllegalStateException("ref counts can't go to zero here: stable="
12684                        + stable + " unstable=" + unstable);
12685            }
12686            conn.stableCount = stable;
12687            conn.unstableCount = unstable;
12688            return !conn.dead;
12689        }
12690    }
12691
12692    public void unstableProviderDied(IBinder connection) {
12693        ContentProviderConnection conn;
12694        try {
12695            conn = (ContentProviderConnection)connection;
12696        } catch (ClassCastException e) {
12697            String msg ="refContentProvider: " + connection
12698                    + " not a ContentProviderConnection";
12699            Slog.w(TAG, msg);
12700            throw new IllegalArgumentException(msg);
12701        }
12702        if (conn == null) {
12703            throw new NullPointerException("connection is null");
12704        }
12705
12706        // Safely retrieve the content provider associated with the connection.
12707        IContentProvider provider;
12708        synchronized (this) {
12709            provider = conn.provider.provider;
12710        }
12711
12712        if (provider == null) {
12713            // Um, yeah, we're way ahead of you.
12714            return;
12715        }
12716
12717        // Make sure the caller is being honest with us.
12718        if (provider.asBinder().pingBinder()) {
12719            // Er, no, still looks good to us.
12720            synchronized (this) {
12721                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12722                        + " says " + conn + " died, but we don't agree");
12723                return;
12724            }
12725        }
12726
12727        // Well look at that!  It's dead!
12728        synchronized (this) {
12729            if (conn.provider.provider != provider) {
12730                // But something changed...  good enough.
12731                return;
12732            }
12733
12734            ProcessRecord proc = conn.provider.proc;
12735            if (proc == null || proc.thread == null) {
12736                // Seems like the process is already cleaned up.
12737                return;
12738            }
12739
12740            // As far as we're concerned, this is just like receiving a
12741            // death notification...  just a bit prematurely.
12742            reportUidInfoMessageLocked(TAG,
12743                    "Process " + proc.processName + " (pid " + proc.pid
12744                            + ") early provider death",
12745                    proc.info.uid);
12746            final long ident = Binder.clearCallingIdentity();
12747            try {
12748                appDiedLocked(proc);
12749            } finally {
12750                Binder.restoreCallingIdentity(ident);
12751            }
12752        }
12753    }
12754
12755    @Override
12756    public void appNotRespondingViaProvider(IBinder connection) {
12757        enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
12758
12759        final ContentProviderConnection conn = (ContentProviderConnection) connection;
12760        if (conn == null) {
12761            Slog.w(TAG, "ContentProviderConnection is null");
12762            return;
12763        }
12764
12765        final ProcessRecord host = conn.provider.proc;
12766        if (host == null) {
12767            Slog.w(TAG, "Failed to find hosting ProcessRecord");
12768            return;
12769        }
12770
12771        mHandler.post(new Runnable() {
12772            @Override
12773            public void run() {
12774                mAppErrors.appNotResponding(host, null, null, false,
12775                        "ContentProvider not responding");
12776            }
12777        });
12778    }
12779
12780    public final void installSystemProviders() {
12781        List<ProviderInfo> providers;
12782        synchronized (this) {
12783            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12784            providers = generateApplicationProvidersLocked(app);
12785            if (providers != null) {
12786                for (int i=providers.size()-1; i>=0; i--) {
12787                    ProviderInfo pi = (ProviderInfo)providers.get(i);
12788                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12789                        Slog.w(TAG, "Not installing system proc provider " + pi.name
12790                                + ": not system .apk");
12791                        providers.remove(i);
12792                    }
12793                }
12794            }
12795        }
12796        if (providers != null) {
12797            mSystemThread.installSystemProviders(providers);
12798        }
12799
12800        synchronized (this) {
12801            mSystemProvidersInstalled = true;
12802        }
12803
12804        mConstants.start(mContext.getContentResolver());
12805        mCoreSettingsObserver = new CoreSettingsObserver(this);
12806        mFontScaleSettingObserver = new FontScaleSettingObserver();
12807        mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
12808        GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
12809
12810        // Now that the settings provider is published we can consider sending
12811        // in a rescue party.
12812        RescueParty.onSettingsProviderPublished(mContext);
12813
12814        //mUsageStatsService.monitorPackages();
12815    }
12816
12817    void startPersistentApps(int matchFlags) {
12818        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12819
12820        synchronized (this) {
12821            try {
12822                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12823                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12824                for (ApplicationInfo app : apps) {
12825                    if (!"android".equals(app.packageName)) {
12826                        addAppLocked(app, null, false, null /* ABI override */);
12827                    }
12828                }
12829            } catch (RemoteException ex) {
12830            }
12831        }
12832    }
12833
12834    /**
12835     * When a user is unlocked, we need to install encryption-unaware providers
12836     * belonging to any running apps.
12837     */
12838    void installEncryptionUnawareProviders(int userId) {
12839        // We're only interested in providers that are encryption unaware, and
12840        // we don't care about uninstalled apps, since there's no way they're
12841        // running at this point.
12842        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12843
12844        synchronized (this) {
12845            final int NP = mProcessNames.getMap().size();
12846            for (int ip = 0; ip < NP; ip++) {
12847                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12848                final int NA = apps.size();
12849                for (int ia = 0; ia < NA; ia++) {
12850                    final ProcessRecord app = apps.valueAt(ia);
12851                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12852
12853                    final int NG = app.pkgList.size();
12854                    for (int ig = 0; ig < NG; ig++) {
12855                        try {
12856                            final String pkgName = app.pkgList.keyAt(ig);
12857                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12858                                    .getPackageInfo(pkgName, matchFlags, userId);
12859                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12860                                for (ProviderInfo pi : pkgInfo.providers) {
12861                                    // TODO: keep in sync with generateApplicationProvidersLocked
12862                                    final boolean processMatch = Objects.equals(pi.processName,
12863                                            app.processName) || pi.multiprocess;
12864                                    final boolean userMatch = isSingleton(pi.processName,
12865                                            pi.applicationInfo, pi.name, pi.flags)
12866                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12867                                    if (processMatch && userMatch) {
12868                                        Log.v(TAG, "Installing " + pi);
12869                                        app.thread.scheduleInstallProvider(pi);
12870                                    } else {
12871                                        Log.v(TAG, "Skipping " + pi);
12872                                    }
12873                                }
12874                            }
12875                        } catch (RemoteException ignored) {
12876                        }
12877                    }
12878                }
12879            }
12880        }
12881    }
12882
12883    /**
12884     * Allows apps to retrieve the MIME type of a URI.
12885     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12886     * users, then it does not need permission to access the ContentProvider.
12887     * Either, it needs cross-user uri grants.
12888     *
12889     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12890     *
12891     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12892     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12893     */
12894    public String getProviderMimeType(Uri uri, int userId) {
12895        enforceNotIsolatedCaller("getProviderMimeType");
12896        final String name = uri.getAuthority();
12897        int callingUid = Binder.getCallingUid();
12898        int callingPid = Binder.getCallingPid();
12899        long ident = 0;
12900        boolean clearedIdentity = false;
12901        userId = mUserController.unsafeConvertIncomingUser(userId);
12902        if (canClearIdentity(callingPid, callingUid, userId)) {
12903            clearedIdentity = true;
12904            ident = Binder.clearCallingIdentity();
12905        }
12906        ContentProviderHolder holder = null;
12907        try {
12908            holder = getContentProviderExternalUnchecked(name, null, userId);
12909            if (holder != null) {
12910                return holder.provider.getType(uri);
12911            }
12912        } catch (RemoteException e) {
12913            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12914            return null;
12915        } catch (Exception e) {
12916            Log.w(TAG, "Exception while determining type of " + uri, e);
12917            return null;
12918        } finally {
12919            // We need to clear the identity to call removeContentProviderExternalUnchecked
12920            if (!clearedIdentity) {
12921                ident = Binder.clearCallingIdentity();
12922            }
12923            try {
12924                if (holder != null) {
12925                    removeContentProviderExternalUnchecked(name, null, userId);
12926                }
12927            } finally {
12928                Binder.restoreCallingIdentity(ident);
12929            }
12930        }
12931
12932        return null;
12933    }
12934
12935    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12936        if (UserHandle.getUserId(callingUid) == userId) {
12937            return true;
12938        }
12939        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12940                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12941                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12942                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12943                return true;
12944        }
12945        return false;
12946    }
12947
12948    // =========================================================
12949    // GLOBAL MANAGEMENT
12950    // =========================================================
12951
12952    @GuardedBy("this")
12953    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12954            boolean isolated, int isolatedUid) {
12955        String proc = customProcess != null ? customProcess : info.processName;
12956        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12957        final int userId = UserHandle.getUserId(info.uid);
12958        int uid = info.uid;
12959        if (isolated) {
12960            if (isolatedUid == 0) {
12961                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12962                while (true) {
12963                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12964                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12965                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12966                    }
12967                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12968                    mNextIsolatedProcessUid++;
12969                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12970                        // No process for this uid, use it.
12971                        break;
12972                    }
12973                    stepsLeft--;
12974                    if (stepsLeft <= 0) {
12975                        return null;
12976                    }
12977                }
12978            } else {
12979                // Special case for startIsolatedProcess (internal only), where
12980                // the uid of the isolated process is specified by the caller.
12981                uid = isolatedUid;
12982            }
12983            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12984
12985            // Register the isolated UID with this application so BatteryStats knows to
12986            // attribute resource usage to the application.
12987            //
12988            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12989            // about the process state of the isolated UID *before* it is registered with the
12990            // owning application.
12991            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12992        }
12993        final ProcessRecord r = new ProcessRecord(this, stats, info, proc, uid);
12994        if (!mBooted && !mBooting
12995                && userId == UserHandle.USER_SYSTEM
12996                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12997            // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
12998            r.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
12999            r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
13000            r.persistent = true;
13001            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
13002        }
13003        if (isolated && isolatedUid != 0) {
13004            // Special case for startIsolatedProcess (internal only) - assume the process
13005            // is required by the system server to prevent it being killed.
13006            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
13007        }
13008        addProcessNameLocked(r);
13009        return r;
13010    }
13011
13012    private boolean uidOnBackgroundWhitelist(final int uid) {
13013        final int appId = UserHandle.getAppId(uid);
13014        final int[] whitelist = mBackgroundAppIdWhitelist;
13015        final int N = whitelist.length;
13016        for (int i = 0; i < N; i++) {
13017            if (appId == whitelist[i]) {
13018                return true;
13019            }
13020        }
13021        return false;
13022    }
13023
13024    @Override
13025    public boolean isBackgroundRestricted(String packageName) {
13026        final int callingUid = Binder.getCallingUid();
13027        final IPackageManager pm = AppGlobals.getPackageManager();
13028        try {
13029            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
13030                    UserHandle.getUserId(callingUid));
13031            if (packageUid != callingUid) {
13032                throw new IllegalArgumentException("Uid " + callingUid
13033                        + " cannot query restriction state for package " + packageName);
13034            }
13035        } catch (RemoteException exc) {
13036            // Ignore.
13037        }
13038        return isBackgroundRestrictedNoCheck(callingUid, packageName);
13039    }
13040
13041    boolean isBackgroundRestrictedNoCheck(final int uid, final String packageName) {
13042        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
13043                uid, packageName);
13044        return mode != AppOpsManager.MODE_ALLOWED;
13045    }
13046
13047    @Override
13048    public void backgroundWhitelistUid(final int uid) {
13049        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13050            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
13051        }
13052
13053        if (DEBUG_BACKGROUND_CHECK) {
13054            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
13055        }
13056        synchronized (this) {
13057            final int N = mBackgroundAppIdWhitelist.length;
13058            int[] newList = new int[N+1];
13059            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
13060            newList[N] = UserHandle.getAppId(uid);
13061            mBackgroundAppIdWhitelist = newList;
13062        }
13063    }
13064
13065    @GuardedBy("this")
13066    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
13067            String abiOverride) {
13068        return addAppLocked(info, customProcess, isolated, false /* disableHiddenApiChecks */,
13069                abiOverride);
13070    }
13071
13072    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
13073            boolean disableHiddenApiChecks, String abiOverride) {
13074        ProcessRecord app;
13075        if (!isolated) {
13076            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
13077                    info.uid, true);
13078        } else {
13079            app = null;
13080        }
13081
13082        if (app == null) {
13083            app = newProcessRecordLocked(info, customProcess, isolated, 0);
13084            updateLruProcessLocked(app, false, null);
13085            updateOomAdjLocked();
13086        }
13087
13088        // This package really, really can not be stopped.
13089        try {
13090            AppGlobals.getPackageManager().setPackageStoppedState(
13091                    info.packageName, false, UserHandle.getUserId(app.uid));
13092        } catch (RemoteException e) {
13093        } catch (IllegalArgumentException e) {
13094            Slog.w(TAG, "Failed trying to unstop package "
13095                    + info.packageName + ": " + e);
13096        }
13097
13098        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
13099            app.persistent = true;
13100            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
13101        }
13102        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
13103            mPersistentStartingProcesses.add(app);
13104            startProcessLocked(app, "added application",
13105                    customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
13106                    abiOverride);
13107        }
13108
13109        return app;
13110    }
13111
13112    public void unhandledBack() {
13113        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
13114                "unhandledBack()");
13115
13116        synchronized(this) {
13117            final long origId = Binder.clearCallingIdentity();
13118            try {
13119                getFocusedStack().unhandledBackLocked();
13120            } finally {
13121                Binder.restoreCallingIdentity(origId);
13122            }
13123        }
13124    }
13125
13126    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
13127        enforceNotIsolatedCaller("openContentUri");
13128        final int userId = UserHandle.getCallingUserId();
13129        final Uri uri = Uri.parse(uriString);
13130        String name = uri.getAuthority();
13131        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
13132        ParcelFileDescriptor pfd = null;
13133        if (cph != null) {
13134            // We record the binder invoker's uid in thread-local storage before
13135            // going to the content provider to open the file.  Later, in the code
13136            // that handles all permissions checks, we look for this uid and use
13137            // that rather than the Activity Manager's own uid.  The effect is that
13138            // we do the check against the caller's permissions even though it looks
13139            // to the content provider like the Activity Manager itself is making
13140            // the request.
13141            Binder token = new Binder();
13142            sCallerIdentity.set(new Identity(
13143                    token, Binder.getCallingPid(), Binder.getCallingUid()));
13144            try {
13145                pfd = cph.provider.openFile(null, uri, "r", null, token);
13146            } catch (FileNotFoundException e) {
13147                // do nothing; pfd will be returned null
13148            } finally {
13149                // Ensure that whatever happens, we clean up the identity state
13150                sCallerIdentity.remove();
13151                // Ensure we're done with the provider.
13152                removeContentProviderExternalUnchecked(name, null, userId);
13153            }
13154        } else {
13155            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
13156        }
13157        return pfd;
13158    }
13159
13160    // Actually is sleeping or shutting down or whatever else in the future
13161    // is an inactive state.
13162    boolean isSleepingOrShuttingDownLocked() {
13163        return isSleepingLocked() || mShuttingDown;
13164    }
13165
13166    boolean isShuttingDownLocked() {
13167        return mShuttingDown;
13168    }
13169
13170    boolean isSleepingLocked() {
13171        return mSleeping;
13172    }
13173
13174    void reportGlobalUsageEventLocked(int event) {
13175        mUsageStatsService.reportEvent("android", mUserController.getCurrentUserId(), event);
13176        int[] profiles = mUserController.getCurrentProfileIds();
13177        if (profiles != null) {
13178            for (int i = profiles.length - 1; i >= 0; i--) {
13179                mUsageStatsService.reportEvent((String)null, profiles[i], event);
13180            }
13181        }
13182    }
13183
13184    void reportCurWakefulnessUsageEventLocked() {
13185        reportGlobalUsageEventLocked(mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE
13186                ? UsageEvents.Event.SCREEN_INTERACTIVE
13187                : UsageEvents.Event.SCREEN_NON_INTERACTIVE);
13188    }
13189
13190    void reportCurKeyguardUsageEventLocked() {
13191        reportGlobalUsageEventLocked(mKeyguardShown
13192                ? UsageEvents.Event.KEYGUARD_SHOWN
13193                : UsageEvents.Event.KEYGUARD_HIDDEN);
13194    }
13195
13196    void onWakefulnessChanged(int wakefulness) {
13197        synchronized(this) {
13198            boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13199            boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13200            mWakefulness = wakefulness;
13201
13202            if (wasAwake != isAwake) {
13203                // Also update state in a special way for running foreground services UI.
13204                mServices.updateScreenStateLocked(isAwake);
13205                reportCurWakefulnessUsageEventLocked();
13206                mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
13207                        .sendToTarget();
13208            }
13209        }
13210    }
13211
13212    @GuardedBy("this")
13213    void finishRunningVoiceLocked() {
13214        if (mRunningVoice != null) {
13215            mRunningVoice = null;
13216            mVoiceWakeLock.release();
13217            updateSleepIfNeededLocked();
13218        }
13219    }
13220
13221    void startTimeTrackingFocusedActivityLocked() {
13222        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
13223        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
13224            mCurAppTimeTracker.start(resumedActivity.packageName);
13225        }
13226    }
13227
13228    @GuardedBy("this")
13229    void updateSleepIfNeededLocked() {
13230        final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
13231        final boolean wasSleeping = mSleeping;
13232
13233        if (!shouldSleep) {
13234            // If wasSleeping is true, we need to wake up activity manager state from when
13235            // we started sleeping. In either case, we need to apply the sleep tokens, which
13236            // will wake up stacks or put them to sleep as appropriate.
13237            if (wasSleeping) {
13238                mSleeping = false;
13239                startTimeTrackingFocusedActivityLocked();
13240                mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
13241                mStackSupervisor.comeOutOfSleepIfNeededLocked();
13242            }
13243            mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
13244            if (wasSleeping) {
13245                updateOomAdjLocked();
13246            }
13247        } else if (!mSleeping && shouldSleep) {
13248            mSleeping = true;
13249            if (mCurAppTimeTracker != null) {
13250                mCurAppTimeTracker.stop();
13251            }
13252            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
13253            mStackSupervisor.goingToSleepLocked();
13254            updateResumedAppTrace(null /* resumed */);
13255            updateOomAdjLocked();
13256        }
13257    }
13258
13259    /** Pokes the task persister. */
13260    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
13261        mRecentTasks.notifyTaskPersisterLocked(task, flush);
13262    }
13263
13264    /**
13265     * Notifies all listeners when the pinned stack animation starts.
13266     */
13267    @Override
13268    public void notifyPinnedStackAnimationStarted() {
13269        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
13270    }
13271
13272    /**
13273     * Notifies all listeners when the pinned stack animation ends.
13274     */
13275    @Override
13276    public void notifyPinnedStackAnimationEnded() {
13277        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
13278    }
13279
13280    @Override
13281    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
13282        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
13283    }
13284
13285    @Override
13286    public boolean shutdown(int timeout) {
13287        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
13288                != PackageManager.PERMISSION_GRANTED) {
13289            throw new SecurityException("Requires permission "
13290                    + android.Manifest.permission.SHUTDOWN);
13291        }
13292
13293        boolean timedout = false;
13294
13295        synchronized(this) {
13296            mShuttingDown = true;
13297            mStackSupervisor.prepareForShutdownLocked();
13298            updateEventDispatchingLocked();
13299            timedout = mStackSupervisor.shutdownLocked(timeout);
13300        }
13301
13302        mAppOpsService.shutdown();
13303        if (mUsageStatsService != null) {
13304            mUsageStatsService.prepareShutdown();
13305        }
13306        mBatteryStatsService.shutdown();
13307        synchronized (this) {
13308            mProcessStats.shutdownLocked();
13309            notifyTaskPersisterLocked(null, true);
13310        }
13311
13312        return timedout;
13313    }
13314
13315    public final void activitySlept(IBinder token) {
13316        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
13317
13318        final long origId = Binder.clearCallingIdentity();
13319
13320        synchronized (this) {
13321            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13322            if (r != null) {
13323                mStackSupervisor.activitySleptLocked(r);
13324            }
13325        }
13326
13327        Binder.restoreCallingIdentity(origId);
13328    }
13329
13330    @GuardedBy("this")
13331    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
13332        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
13333        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
13334        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
13335            boolean wasRunningVoice = mRunningVoice != null;
13336            mRunningVoice = session;
13337            if (!wasRunningVoice) {
13338                mVoiceWakeLock.acquire();
13339                updateSleepIfNeededLocked();
13340            }
13341        }
13342    }
13343
13344    private void updateEventDispatchingLocked() {
13345        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
13346    }
13347
13348    @Override
13349    public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
13350            int secondaryDisplayShowing) {
13351        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
13352                != PackageManager.PERMISSION_GRANTED) {
13353            throw new SecurityException("Requires permission "
13354                    + android.Manifest.permission.DEVICE_POWER);
13355        }
13356
13357        synchronized(this) {
13358            long ident = Binder.clearCallingIdentity();
13359            if (mKeyguardShown != keyguardShowing) {
13360                mKeyguardShown = keyguardShowing;
13361                reportCurKeyguardUsageEventLocked();
13362            }
13363            try {
13364                mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
13365                        secondaryDisplayShowing);
13366            } finally {
13367                Binder.restoreCallingIdentity(ident);
13368            }
13369        }
13370
13371        mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, keyguardShowing ? 1 : 0, 0)
13372                .sendToTarget();
13373    }
13374
13375    @Override
13376    public void notifyLockedProfile(@UserIdInt int userId) {
13377        try {
13378            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
13379                throw new SecurityException("Only privileged app can call notifyLockedProfile");
13380            }
13381        } catch (RemoteException ex) {
13382            throw new SecurityException("Fail to check is caller a privileged app", ex);
13383        }
13384
13385        synchronized (this) {
13386            final long ident = Binder.clearCallingIdentity();
13387            try {
13388                if (mUserController.shouldConfirmCredentials(userId)) {
13389                    if (mKeyguardController.isKeyguardLocked()) {
13390                        // Showing launcher to avoid user entering credential twice.
13391                        final int currentUserId = mUserController.getCurrentUserId();
13392                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
13393                    }
13394                    mStackSupervisor.lockAllProfileTasks(userId);
13395                }
13396            } finally {
13397                Binder.restoreCallingIdentity(ident);
13398            }
13399        }
13400    }
13401
13402    @Override
13403    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
13404        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
13405        synchronized (this) {
13406            final long ident = Binder.clearCallingIdentity();
13407            try {
13408                intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
13409                        FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
13410                        FLAG_ACTIVITY_TASK_ON_HOME);
13411                ActivityOptions activityOptions = options != null
13412                        ? new ActivityOptions(options)
13413                        : ActivityOptions.makeBasic();
13414                activityOptions.setLaunchTaskId(
13415                        mStackSupervisor.getHomeActivity().getTask().taskId);
13416                mContext.startActivityAsUser(intent, activityOptions.toBundle(),
13417                        UserHandle.CURRENT);
13418            } finally {
13419                Binder.restoreCallingIdentity(ident);
13420            }
13421        }
13422    }
13423
13424    @Override
13425    public void stopAppSwitches() {
13426        enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
13427        synchronized(this) {
13428            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
13429                    + APP_SWITCH_DELAY_TIME;
13430            mDidAppSwitch = false;
13431            mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
13432        }
13433    }
13434
13435    public void resumeAppSwitches() {
13436        enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
13437        synchronized(this) {
13438            // Note that we don't execute any pending app switches... we will
13439            // let those wait until either the timeout, or the next start
13440            // activity request.
13441            mAppSwitchesAllowedTime = 0;
13442        }
13443    }
13444
13445    boolean checkAllowAppSwitchUid(int uid) {
13446        ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
13447        if (types != null) {
13448            for (int i = types.size() - 1; i >= 0; i--) {
13449                if (types.valueAt(i).intValue() == uid) {
13450                    return true;
13451                }
13452            }
13453        }
13454        return false;
13455    }
13456
13457    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
13458            int callingPid, int callingUid, String name) {
13459        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
13460            return true;
13461        }
13462
13463        if (mRecentTasks.isCallerRecents(sourceUid)) {
13464            return true;
13465        }
13466
13467        int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
13468        if (perm == PackageManager.PERMISSION_GRANTED) {
13469            return true;
13470        }
13471        if (checkAllowAppSwitchUid(sourceUid)) {
13472            return true;
13473        }
13474
13475        // If the actual IPC caller is different from the logical source, then
13476        // also see if they are allowed to control app switches.
13477        if (callingUid != -1 && callingUid != sourceUid) {
13478            perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
13479            if (perm == PackageManager.PERMISSION_GRANTED) {
13480                return true;
13481            }
13482            if (checkAllowAppSwitchUid(callingUid)) {
13483                return true;
13484            }
13485        }
13486
13487        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
13488        return false;
13489    }
13490
13491    public void setDebugApp(String packageName, boolean waitForDebugger,
13492            boolean persistent) {
13493        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
13494                "setDebugApp()");
13495
13496        long ident = Binder.clearCallingIdentity();
13497        try {
13498            // Note that this is not really thread safe if there are multiple
13499            // callers into it at the same time, but that's not a situation we
13500            // care about.
13501            if (persistent) {
13502                final ContentResolver resolver = mContext.getContentResolver();
13503                Settings.Global.putString(
13504                    resolver, Settings.Global.DEBUG_APP,
13505                    packageName);
13506                Settings.Global.putInt(
13507                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
13508                    waitForDebugger ? 1 : 0);
13509            }
13510
13511            synchronized (this) {
13512                if (!persistent) {
13513                    mOrigDebugApp = mDebugApp;
13514                    mOrigWaitForDebugger = mWaitForDebugger;
13515                }
13516                mDebugApp = packageName;
13517                mWaitForDebugger = waitForDebugger;
13518                mDebugTransient = !persistent;
13519                if (packageName != null) {
13520                    forceStopPackageLocked(packageName, -1, false, false, true, true,
13521                            false, UserHandle.USER_ALL, "set debug app");
13522                }
13523            }
13524        } finally {
13525            Binder.restoreCallingIdentity(ident);
13526        }
13527    }
13528
13529    /**
13530     * Set or remove an agent to be run whenever an app with the given process name starts.
13531     *
13532     * This method will not check whether the given process name matches a debuggable app. That
13533     * would require scanning all current packages, and a rescan when new packages are installed
13534     * or updated.
13535     *
13536     * Instead, do the check when an application is started and matched to a stored agent.
13537     *
13538     * @param packageName the process name of the app.
13539     * @param agent the agent string to be used, or null to remove any previously set agent.
13540     */
13541    @Override
13542    public void setAgentApp(@NonNull String packageName, @Nullable String agent) {
13543        synchronized (this) {
13544            // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13545            // its own permission.
13546            if (checkCallingPermission(
13547                    android.Manifest.permission.SET_ACTIVITY_WATCHER) !=
13548                        PackageManager.PERMISSION_GRANTED) {
13549                throw new SecurityException(
13550                        "Requires permission " + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13551            }
13552
13553            if (agent == null) {
13554                if (mAppAgentMap != null) {
13555                    mAppAgentMap.remove(packageName);
13556                    if (mAppAgentMap.isEmpty()) {
13557                        mAppAgentMap = null;
13558                    }
13559                }
13560            } else {
13561                if (mAppAgentMap == null) {
13562                    mAppAgentMap = new HashMap<>();
13563                }
13564                if (mAppAgentMap.size() >= 100) {
13565                    // Limit the size of the map, to avoid OOMEs.
13566                    Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName
13567                            + "/" + agent);
13568                    return;
13569                }
13570                mAppAgentMap.put(packageName, agent);
13571            }
13572        }
13573    }
13574
13575    void setTrackAllocationApp(ApplicationInfo app, String processName) {
13576        synchronized (this) {
13577            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13578            if (!isDebuggable) {
13579                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13580                    throw new SecurityException("Process not debuggable: " + app.packageName);
13581                }
13582            }
13583
13584            mTrackAllocationApp = processName;
13585        }
13586    }
13587
13588    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
13589        synchronized (this) {
13590            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13591            if (!isDebuggable) {
13592                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13593                    throw new SecurityException("Process not debuggable: " + app.packageName);
13594                }
13595            }
13596            mProfileApp = processName;
13597
13598            if (mProfilerInfo != null) {
13599                if (mProfilerInfo.profileFd != null) {
13600                    try {
13601                        mProfilerInfo.profileFd.close();
13602                    } catch (IOException e) {
13603                    }
13604                }
13605            }
13606            mProfilerInfo = new ProfilerInfo(profilerInfo);
13607            mProfileType = 0;
13608        }
13609    }
13610
13611    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
13612        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13613        if (!isDebuggable) {
13614            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13615                throw new SecurityException("Process not debuggable: " + app.packageName);
13616            }
13617        }
13618        mNativeDebuggingApp = processName;
13619    }
13620
13621    @Override
13622    public void setAlwaysFinish(boolean enabled) {
13623        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
13624                "setAlwaysFinish()");
13625
13626        long ident = Binder.clearCallingIdentity();
13627        try {
13628            Settings.Global.putInt(
13629                    mContext.getContentResolver(),
13630                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
13631
13632            synchronized (this) {
13633                mAlwaysFinishActivities = enabled;
13634            }
13635        } finally {
13636            Binder.restoreCallingIdentity(ident);
13637        }
13638    }
13639
13640    @Override
13641    public void setActivityController(IActivityController controller, boolean imAMonkey) {
13642        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13643                "setActivityController()");
13644        synchronized (this) {
13645            mController = controller;
13646            mControllerIsAMonkey = imAMonkey;
13647            Watchdog.getInstance().setActivityController(controller);
13648        }
13649    }
13650
13651    @Override
13652    public void setUserIsMonkey(boolean userIsMonkey) {
13653        synchronized (this) {
13654            synchronized (mPidsSelfLocked) {
13655                final int callingPid = Binder.getCallingPid();
13656                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
13657                if (proc == null) {
13658                    throw new SecurityException("Unknown process: " + callingPid);
13659                }
13660                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
13661                    throw new SecurityException("Only an instrumentation process "
13662                            + "with a UiAutomation can call setUserIsMonkey");
13663                }
13664            }
13665            mUserIsMonkey = userIsMonkey;
13666        }
13667    }
13668
13669    @Override
13670    public boolean isUserAMonkey() {
13671        synchronized (this) {
13672            // If there is a controller also implies the user is a monkey.
13673            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
13674        }
13675    }
13676
13677    /**
13678     * @deprecated This method is only used by a few internal components and it will soon be
13679     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13680     * No new code should be calling it.
13681     */
13682    @Deprecated
13683    @Override
13684    public void requestBugReport(int bugreportType) {
13685        String extraOptions = null;
13686        switch (bugreportType) {
13687            case ActivityManager.BUGREPORT_OPTION_FULL:
13688                // Default options.
13689                break;
13690            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
13691                extraOptions = "bugreportplus";
13692                break;
13693            case ActivityManager.BUGREPORT_OPTION_REMOTE:
13694                extraOptions = "bugreportremote";
13695                break;
13696            case ActivityManager.BUGREPORT_OPTION_WEAR:
13697                extraOptions = "bugreportwear";
13698                break;
13699            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
13700                extraOptions = "bugreporttelephony";
13701                break;
13702            case ActivityManager.BUGREPORT_OPTION_WIFI:
13703                extraOptions = "bugreportwifi";
13704                break;
13705            default:
13706                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
13707                        + bugreportType);
13708        }
13709        // Always log caller, even if it does not have permission to dump.
13710        String type = extraOptions == null ? "bugreport" : extraOptions;
13711        Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
13712
13713        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13714        if (extraOptions != null) {
13715            SystemProperties.set("dumpstate.options", extraOptions);
13716        }
13717        SystemProperties.set("ctl.start", "bugreport");
13718    }
13719
13720    /**
13721     * @deprecated This method is only used by a few internal components and it will soon be
13722     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13723     * No new code should be calling it.
13724     */
13725    @Deprecated
13726    private void requestBugReportWithDescription(String shareTitle, String shareDescription,
13727                                                 int bugreportType) {
13728        if (!TextUtils.isEmpty(shareTitle)) {
13729            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13730                String errorStr = "shareTitle should be less than " +
13731                        MAX_BUGREPORT_TITLE_SIZE + " characters";
13732                throw new IllegalArgumentException(errorStr);
13733            } else {
13734                if (!TextUtils.isEmpty(shareDescription)) {
13735                    int length;
13736                    try {
13737                        length = shareDescription.getBytes("UTF-8").length;
13738                    } catch (UnsupportedEncodingException e) {
13739                        String errorStr = "shareDescription: UnsupportedEncodingException";
13740                        throw new IllegalArgumentException(errorStr);
13741                    }
13742                    if (length > SystemProperties.PROP_VALUE_MAX) {
13743                        String errorStr = "shareTitle should be less than " +
13744                                SystemProperties.PROP_VALUE_MAX + " bytes";
13745                        throw new IllegalArgumentException(errorStr);
13746                    } else {
13747                        SystemProperties.set("dumpstate.options.description", shareDescription);
13748                    }
13749                }
13750                SystemProperties.set("dumpstate.options.title", shareTitle);
13751            }
13752        }
13753
13754        Slog.d(TAG, "Bugreport notification title " + shareTitle
13755                + " description " + shareDescription);
13756        requestBugReport(bugreportType);
13757    }
13758
13759    /**
13760     * @deprecated This method is only used by a few internal components and it will soon be
13761     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13762     * No new code should be calling it.
13763     */
13764    @Deprecated
13765    @Override
13766    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13767        requestBugReportWithDescription(shareTitle, shareDescription,
13768                ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13769    }
13770
13771    /**
13772     * @deprecated This method is only used by a few internal components and it will soon be
13773     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13774     * No new code should be calling it.
13775     */
13776    @Deprecated
13777    @Override
13778    public void requestWifiBugReport(String shareTitle, String shareDescription) {
13779        requestBugReportWithDescription(shareTitle, shareDescription,
13780                ActivityManager.BUGREPORT_OPTION_WIFI);
13781    }
13782
13783
13784    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13785        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13786    }
13787
13788    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13789        if (r != null && (r.instr != null || r.usingWrapper)) {
13790            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13791        }
13792        return KEY_DISPATCHING_TIMEOUT;
13793    }
13794
13795    @Override
13796    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13797        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13798                != PackageManager.PERMISSION_GRANTED) {
13799            throw new SecurityException("Requires permission "
13800                    + android.Manifest.permission.FILTER_EVENTS);
13801        }
13802        ProcessRecord proc;
13803        long timeout;
13804        synchronized (this) {
13805            synchronized (mPidsSelfLocked) {
13806                proc = mPidsSelfLocked.get(pid);
13807            }
13808            timeout = getInputDispatchingTimeoutLocked(proc);
13809        }
13810
13811        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13812            return -1;
13813        }
13814
13815        return timeout;
13816    }
13817
13818    /**
13819     * Handle input dispatching timeouts.
13820     * Returns whether input dispatching should be aborted or not.
13821     */
13822    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13823            final ActivityRecord activity, final ActivityRecord parent,
13824            final boolean aboveSystem, String reason) {
13825        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13826                != PackageManager.PERMISSION_GRANTED) {
13827            throw new SecurityException("Requires permission "
13828                    + android.Manifest.permission.FILTER_EVENTS);
13829        }
13830
13831        final String annotation;
13832        if (reason == null) {
13833            annotation = "Input dispatching timed out";
13834        } else {
13835            annotation = "Input dispatching timed out (" + reason + ")";
13836        }
13837
13838        if (proc != null) {
13839            synchronized (this) {
13840                if (proc.debugging) {
13841                    return false;
13842                }
13843
13844                if (proc.instr != null) {
13845                    Bundle info = new Bundle();
13846                    info.putString("shortMsg", "keyDispatchingTimedOut");
13847                    info.putString("longMsg", annotation);
13848                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13849                    return true;
13850                }
13851            }
13852            mHandler.post(new Runnable() {
13853                @Override
13854                public void run() {
13855                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13856                }
13857            });
13858        }
13859
13860        return true;
13861    }
13862
13863    @Override
13864    public Bundle getAssistContextExtras(int requestType) {
13865        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13866                null, null, true /* focused */, true /* newSessionId */,
13867                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13868        if (pae == null) {
13869            return null;
13870        }
13871        synchronized (pae) {
13872            while (!pae.haveResult) {
13873                try {
13874                    pae.wait();
13875                } catch (InterruptedException e) {
13876                }
13877            }
13878        }
13879        synchronized (this) {
13880            buildAssistBundleLocked(pae, pae.result);
13881            mPendingAssistExtras.remove(pae);
13882            mUiHandler.removeCallbacks(pae);
13883        }
13884        return pae.extras;
13885    }
13886
13887    @Override
13888    public boolean isAssistDataAllowedOnCurrentActivity() {
13889        int userId;
13890        synchronized (this) {
13891            final ActivityStack focusedStack = getFocusedStack();
13892            if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
13893                return false;
13894            }
13895
13896            final ActivityRecord activity = focusedStack.getTopActivity();
13897            if (activity == null) {
13898                return false;
13899            }
13900            userId = activity.userId;
13901        }
13902        return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
13903    }
13904
13905    @Override
13906    public boolean showAssistFromActivity(IBinder token, Bundle args) {
13907        long ident = Binder.clearCallingIdentity();
13908        try {
13909            synchronized (this) {
13910                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13911                ActivityRecord top = getFocusedStack().getTopActivity();
13912                if (top != caller) {
13913                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13914                            + " is not current top " + top);
13915                    return false;
13916                }
13917                if (!top.nowVisible) {
13918                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13919                            + " is not visible");
13920                    return false;
13921                }
13922            }
13923            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13924                    token);
13925        } finally {
13926            Binder.restoreCallingIdentity(ident);
13927        }
13928    }
13929
13930    @Override
13931    public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
13932            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13933        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13934                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13935                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13936    }
13937
13938    @Override
13939    public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
13940            IBinder activityToken, int flags) {
13941        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13942                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13943                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13944    }
13945
13946    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13947            IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13948            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13949            int flags) {
13950        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13951                "enqueueAssistContext()");
13952
13953        synchronized (this) {
13954            ActivityRecord activity = getFocusedStack().getTopActivity();
13955            if (activity == null) {
13956                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13957                return null;
13958            }
13959            if (activity.app == null || activity.app.thread == null) {
13960                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13961                return null;
13962            }
13963            if (focused) {
13964                if (activityToken != null) {
13965                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13966                    if (activity != caller) {
13967                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13968                                + " is not current top " + activity);
13969                        return null;
13970                    }
13971                }
13972            } else {
13973                activity = ActivityRecord.forTokenLocked(activityToken);
13974                if (activity == null) {
13975                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13976                            + " couldn't be found");
13977                    return null;
13978                }
13979                if (activity.app == null || activity.app.thread == null) {
13980                    Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13981                    return null;
13982                }
13983            }
13984
13985            PendingAssistExtras pae;
13986            Bundle extras = new Bundle();
13987            if (args != null) {
13988                extras.putAll(args);
13989            }
13990            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13991            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13992
13993            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13994                    userHandle);
13995            pae.isHome = activity.isActivityTypeHome();
13996
13997            // Increment the sessionId if necessary
13998            if (newSessionId) {
13999                mViSessionId++;
14000            }
14001            try {
14002                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
14003                        mViSessionId, flags);
14004                mPendingAssistExtras.add(pae);
14005                mUiHandler.postDelayed(pae, timeout);
14006            } catch (RemoteException e) {
14007                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
14008                return null;
14009            }
14010            return pae;
14011        }
14012    }
14013
14014    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
14015        IAssistDataReceiver receiver;
14016        synchronized (this) {
14017            mPendingAssistExtras.remove(pae);
14018            receiver = pae.receiver;
14019        }
14020        if (receiver != null) {
14021            // Caller wants result sent back to them.
14022            Bundle sendBundle = new Bundle();
14023            // At least return the receiver extras
14024            sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
14025            try {
14026                pae.receiver.onHandleAssistData(sendBundle);
14027            } catch (RemoteException e) {
14028            }
14029        }
14030    }
14031
14032    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
14033        if (result != null) {
14034            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
14035        }
14036        if (pae.hint != null) {
14037            pae.extras.putBoolean(pae.hint, true);
14038        }
14039    }
14040
14041    /** Called from an app when assist data is ready. */
14042    @Override
14043    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
14044            AssistContent content, Uri referrer) {
14045        PendingAssistExtras pae = (PendingAssistExtras)token;
14046        synchronized (pae) {
14047            pae.result = extras;
14048            pae.structure = structure;
14049            pae.content = content;
14050            if (referrer != null) {
14051                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
14052            }
14053            if (structure != null) {
14054                structure.setHomeActivity(pae.isHome);
14055            }
14056            pae.haveResult = true;
14057            pae.notifyAll();
14058            if (pae.intent == null && pae.receiver == null) {
14059                // Caller is just waiting for the result.
14060                return;
14061            }
14062        }
14063        // We are now ready to launch the assist activity.
14064        IAssistDataReceiver sendReceiver = null;
14065        Bundle sendBundle = null;
14066        synchronized (this) {
14067            buildAssistBundleLocked(pae, extras);
14068            boolean exists = mPendingAssistExtras.remove(pae);
14069            mUiHandler.removeCallbacks(pae);
14070            if (!exists) {
14071                // Timed out.
14072                return;
14073            }
14074
14075            if ((sendReceiver=pae.receiver) != null) {
14076                // Caller wants result sent back to them.
14077                sendBundle = new Bundle();
14078                sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
14079                sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
14080                sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
14081                sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
14082            }
14083        }
14084        if (sendReceiver != null) {
14085            try {
14086                sendReceiver.onHandleAssistData(sendBundle);
14087            } catch (RemoteException e) {
14088            }
14089            return;
14090        }
14091
14092        final long ident = Binder.clearCallingIdentity();
14093        try {
14094            if (TextUtils.equals(pae.intent.getAction(),
14095                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
14096                pae.intent.putExtras(pae.extras);
14097                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
14098            } else {
14099                pae.intent.replaceExtras(pae.extras);
14100                pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
14101                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
14102                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
14103                closeSystemDialogs("assist");
14104
14105                try {
14106                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
14107                } catch (ActivityNotFoundException e) {
14108                    Slog.w(TAG, "No activity to handle assist action.", e);
14109                }
14110            }
14111        } finally {
14112            Binder.restoreCallingIdentity(ident);
14113        }
14114    }
14115
14116    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
14117            Bundle args) {
14118        return enqueueAssistContext(requestType, intent, hint, null, null, null,
14119                true /* focused */, true /* newSessionId */, userHandle, args,
14120                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
14121    }
14122
14123    public void registerProcessObserver(IProcessObserver observer) {
14124        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
14125                "registerProcessObserver()");
14126        synchronized (this) {
14127            mProcessObservers.register(observer);
14128        }
14129    }
14130
14131    @Override
14132    public void unregisterProcessObserver(IProcessObserver observer) {
14133        synchronized (this) {
14134            mProcessObservers.unregister(observer);
14135        }
14136    }
14137
14138    @Override
14139    public int getUidProcessState(int uid, String callingPackage) {
14140        if (!hasUsageStatsPermission(callingPackage)) {
14141            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14142                    "getUidProcessState");
14143        }
14144
14145        synchronized (this) {
14146            UidRecord uidRec = mActiveUids.get(uid);
14147            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
14148        }
14149    }
14150
14151    @Override
14152    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
14153            String callingPackage) {
14154        if (!hasUsageStatsPermission(callingPackage)) {
14155            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14156                    "registerUidObserver");
14157        }
14158        synchronized (this) {
14159            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
14160                    callingPackage, which, cutpoint));
14161        }
14162    }
14163
14164    @Override
14165    public void unregisterUidObserver(IUidObserver observer) {
14166        synchronized (this) {
14167            mUidObservers.unregister(observer);
14168        }
14169    }
14170
14171    @Override
14172    public boolean isUidActive(int uid, String callingPackage) {
14173        if (!hasUsageStatsPermission(callingPackage)) {
14174            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14175                    "isUidActive");
14176        }
14177        synchronized (this) {
14178            return isUidActiveLocked(uid);
14179        }
14180    }
14181
14182    boolean isUidActiveLocked(int uid) {
14183        final UidRecord uidRecord = mActiveUids.get(uid);
14184        return uidRecord != null && !uidRecord.setIdle;
14185    }
14186
14187    @Override
14188    public boolean convertFromTranslucent(IBinder token) {
14189        final long origId = Binder.clearCallingIdentity();
14190        try {
14191            synchronized (this) {
14192                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14193                if (r == null) {
14194                    return false;
14195                }
14196                final boolean translucentChanged = r.changeWindowTranslucency(true);
14197                if (translucentChanged) {
14198                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14199                }
14200                mWindowManager.setAppFullscreen(token, true);
14201                return translucentChanged;
14202            }
14203        } finally {
14204            Binder.restoreCallingIdentity(origId);
14205        }
14206    }
14207
14208    @Override
14209    public boolean convertToTranslucent(IBinder token, Bundle options) {
14210        SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
14211        final long origId = Binder.clearCallingIdentity();
14212        try {
14213            synchronized (this) {
14214                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14215                if (r == null) {
14216                    return false;
14217                }
14218                final TaskRecord task = r.getTask();
14219                int index = task.mActivities.lastIndexOf(r);
14220                if (index > 0) {
14221                    ActivityRecord under = task.mActivities.get(index - 1);
14222                    under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
14223                }
14224                final boolean translucentChanged = r.changeWindowTranslucency(false);
14225                if (translucentChanged) {
14226                    r.getStack().convertActivityToTranslucent(r);
14227                }
14228                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14229                mWindowManager.setAppFullscreen(token, false);
14230                return translucentChanged;
14231            }
14232        } finally {
14233            Binder.restoreCallingIdentity(origId);
14234        }
14235    }
14236
14237    @Override
14238    public Bundle getActivityOptions(IBinder token) {
14239        final long origId = Binder.clearCallingIdentity();
14240        try {
14241            synchronized (this) {
14242                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14243                if (r != null) {
14244                    final ActivityOptions activityOptions = r.takeOptionsLocked();
14245                    return activityOptions == null ? null : activityOptions.toBundle();
14246                }
14247                return null;
14248            }
14249        } finally {
14250            Binder.restoreCallingIdentity(origId);
14251        }
14252    }
14253
14254    @Override
14255    public void setImmersive(IBinder token, boolean immersive) {
14256        synchronized(this) {
14257            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14258            if (r == null) {
14259                throw new IllegalArgumentException();
14260            }
14261            r.immersive = immersive;
14262
14263            // update associated state if we're frontmost
14264            if (r == mStackSupervisor.getResumedActivityLocked()) {
14265                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
14266                applyUpdateLockStateLocked(r);
14267            }
14268        }
14269    }
14270
14271    @Override
14272    public boolean isImmersive(IBinder token) {
14273        synchronized (this) {
14274            ActivityRecord r = ActivityRecord.isInStackLocked(token);
14275            if (r == null) {
14276                throw new IllegalArgumentException();
14277            }
14278            return r.immersive;
14279        }
14280    }
14281
14282    @Override
14283    public void setVrThread(int tid) {
14284        enforceSystemHasVrFeature();
14285        synchronized (this) {
14286            synchronized (mPidsSelfLocked) {
14287                final int pid = Binder.getCallingPid();
14288                final ProcessRecord proc = mPidsSelfLocked.get(pid);
14289                mVrController.setVrThreadLocked(tid, pid, proc);
14290            }
14291        }
14292    }
14293
14294    @Override
14295    public void setPersistentVrThread(int tid) {
14296        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
14297            final String msg = "Permission Denial: setPersistentVrThread() from pid="
14298                    + Binder.getCallingPid()
14299                    + ", uid=" + Binder.getCallingUid()
14300                    + " requires " + permission.RESTRICTED_VR_ACCESS;
14301            Slog.w(TAG, msg);
14302            throw new SecurityException(msg);
14303        }
14304        enforceSystemHasVrFeature();
14305        synchronized (this) {
14306            synchronized (mPidsSelfLocked) {
14307                final int pid = Binder.getCallingPid();
14308                final ProcessRecord proc = mPidsSelfLocked.get(pid);
14309                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
14310            }
14311        }
14312    }
14313
14314    /**
14315     * Schedule the given thread a normal scheduling priority.
14316     *
14317     * @param tid the tid of the thread to adjust the scheduling of.
14318     * @param suppressLogs {@code true} if any error logging should be disabled.
14319     *
14320     * @return {@code true} if this succeeded.
14321     */
14322    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
14323        try {
14324            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
14325            return true;
14326        } catch (IllegalArgumentException e) {
14327            if (!suppressLogs) {
14328                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14329            }
14330        } catch (SecurityException e) {
14331            if (!suppressLogs) {
14332                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14333            }
14334        }
14335        return false;
14336    }
14337
14338    /**
14339     * Schedule the given thread an FIFO scheduling priority.
14340     *
14341     * @param tid the tid of the thread to adjust the scheduling of.
14342     * @param suppressLogs {@code true} if any error logging should be disabled.
14343     *
14344     * @return {@code true} if this succeeded.
14345     */
14346    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
14347        try {
14348            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
14349            return true;
14350        } catch (IllegalArgumentException e) {
14351            if (!suppressLogs) {
14352                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14353            }
14354        } catch (SecurityException e) {
14355            if (!suppressLogs) {
14356                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14357            }
14358        }
14359        return false;
14360    }
14361
14362    /**
14363     * Check that we have the features required for VR-related API calls, and throw an exception if
14364     * not.
14365     */
14366    private void enforceSystemHasVrFeature() {
14367        if (!mContext.getPackageManager().hasSystemFeature(
14368                PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
14369            throw new UnsupportedOperationException("VR mode not supported on this device!");
14370        }
14371    }
14372
14373    @Override
14374    public void setRenderThread(int tid) {
14375        synchronized (this) {
14376            ProcessRecord proc;
14377            int pid = Binder.getCallingPid();
14378            if (pid == Process.myPid()) {
14379                demoteSystemServerRenderThread(tid);
14380                return;
14381            }
14382            synchronized (mPidsSelfLocked) {
14383                proc = mPidsSelfLocked.get(pid);
14384                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
14385                    // ensure the tid belongs to the process
14386                    if (!isThreadInProcess(pid, tid)) {
14387                        throw new IllegalArgumentException(
14388                            "Render thread does not belong to process");
14389                    }
14390                    proc.renderThreadTid = tid;
14391                    if (DEBUG_OOM_ADJ) {
14392                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
14393                    }
14394                    // promote to FIFO now
14395                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
14396                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
14397                        if (mUseFifoUiScheduling) {
14398                            setThreadScheduler(proc.renderThreadTid,
14399                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
14400                        } else {
14401                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
14402                        }
14403                    }
14404                } else {
14405                    if (DEBUG_OOM_ADJ) {
14406                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
14407                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
14408                               mUseFifoUiScheduling);
14409                    }
14410                }
14411            }
14412        }
14413    }
14414
14415    /**
14416     * We only use RenderThread in system_server to store task snapshots to the disk, which should
14417     * happen in the background. Thus, demote render thread from system_server to a lower priority.
14418     *
14419     * @param tid the tid of the RenderThread
14420     */
14421    private void demoteSystemServerRenderThread(int tid) {
14422        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
14423    }
14424
14425    @Override
14426    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
14427        enforceSystemHasVrFeature();
14428
14429        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14430
14431        ActivityRecord r;
14432        synchronized (this) {
14433            r = ActivityRecord.isInStackLocked(token);
14434        }
14435
14436        if (r == null) {
14437            throw new IllegalArgumentException();
14438        }
14439
14440        int err;
14441        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
14442                VrManagerInternal.NO_ERROR) {
14443            return err;
14444        }
14445
14446        // Clear the binder calling uid since this path may call moveToTask().
14447        final long callingId = Binder.clearCallingIdentity();
14448        try {
14449            synchronized(this) {
14450                r.requestedVrComponent = (enabled) ? packageName : null;
14451
14452                // Update associated state if this activity is currently focused
14453                if (r == mStackSupervisor.getResumedActivityLocked()) {
14454                    applyUpdateVrModeLocked(r);
14455                }
14456                return 0;
14457            }
14458        } finally {
14459            Binder.restoreCallingIdentity(callingId);
14460        }
14461    }
14462
14463    @Override
14464    public boolean isVrModePackageEnabled(ComponentName packageName) {
14465        enforceSystemHasVrFeature();
14466
14467        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14468
14469        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
14470                VrManagerInternal.NO_ERROR;
14471    }
14472
14473    public boolean isTopActivityImmersive() {
14474        enforceNotIsolatedCaller("startActivity");
14475        synchronized (this) {
14476            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
14477            return (r != null) ? r.immersive : false;
14478        }
14479    }
14480
14481    /**
14482     * @return whether the system should disable UI modes incompatible with VR mode.
14483     */
14484    boolean shouldDisableNonVrUiLocked() {
14485        return mVrController.shouldDisableNonVrUiLocked();
14486    }
14487
14488    @Override
14489    public boolean isTopOfTask(IBinder token) {
14490        synchronized (this) {
14491            ActivityRecord r = ActivityRecord.isInStackLocked(token);
14492            if (r == null) {
14493                throw new IllegalArgumentException();
14494            }
14495            return r.getTask().getTopActivity() == r;
14496        }
14497    }
14498
14499    @Override
14500    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
14501        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
14502            String msg = "Permission Denial: setHasTopUi() from pid="
14503                    + Binder.getCallingPid()
14504                    + ", uid=" + Binder.getCallingUid()
14505                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
14506            Slog.w(TAG, msg);
14507            throw new SecurityException(msg);
14508        }
14509        final int pid = Binder.getCallingPid();
14510        final long origId = Binder.clearCallingIdentity();
14511        try {
14512            synchronized (this) {
14513                boolean changed = false;
14514                ProcessRecord pr;
14515                synchronized (mPidsSelfLocked) {
14516                    pr = mPidsSelfLocked.get(pid);
14517                    if (pr == null) {
14518                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
14519                        return;
14520                    }
14521                    if (pr.hasTopUi != hasTopUi) {
14522                        if (DEBUG_OOM_ADJ) {
14523                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
14524                        }
14525                        pr.hasTopUi = hasTopUi;
14526                        changed = true;
14527                    }
14528                }
14529                if (changed) {
14530                    updateOomAdjLocked(pr, true);
14531                }
14532            }
14533        } finally {
14534            Binder.restoreCallingIdentity(origId);
14535        }
14536    }
14537
14538    void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
14539        synchronized (ActivityManagerService.this) {
14540            final ProcessRecord pr;
14541            synchronized (mPidsSelfLocked) {
14542                pr = mPidsSelfLocked.get(pid);
14543                if (pr == null) {
14544                    Slog.w(TAG, "setRunningRemoteAnimation called on unknown pid: " + pid);
14545                    return;
14546                }
14547            }
14548            if (pr.runningRemoteAnimation == runningRemoteAnimation) {
14549                return;
14550            }
14551            pr.runningRemoteAnimation = runningRemoteAnimation;
14552            if (DEBUG_OOM_ADJ) {
14553                Slog.i(TAG, "Setting runningRemoteAnimation=" + pr.runningRemoteAnimation
14554                        + " for pid=" + pid);
14555            }
14556            updateOomAdjLocked(pr, true);
14557        }
14558    }
14559
14560    public final void enterSafeMode() {
14561        synchronized(this) {
14562            // It only makes sense to do this before the system is ready
14563            // and started launching other packages.
14564            if (!mSystemReady) {
14565                try {
14566                    AppGlobals.getPackageManager().enterSafeMode();
14567                } catch (RemoteException e) {
14568                }
14569            }
14570
14571            mSafeMode = true;
14572        }
14573    }
14574
14575    public final void showSafeModeOverlay() {
14576        View v = LayoutInflater.from(mContext).inflate(
14577                com.android.internal.R.layout.safe_mode, null);
14578        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
14579        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
14580        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
14581        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
14582        lp.gravity = Gravity.BOTTOM | Gravity.START;
14583        lp.format = v.getBackground().getOpacity();
14584        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
14585                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
14586        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
14587        ((WindowManager)mContext.getSystemService(
14588                Context.WINDOW_SERVICE)).addView(v, lp);
14589    }
14590
14591    @Override
14592    public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
14593            String sourcePkg, String tag) {
14594        if (workSource != null && workSource.isEmpty()) {
14595            workSource = null;
14596        }
14597
14598        if (sourceUid <= 0 && workSource == null) {
14599            // Try and derive a UID to attribute things to based on the caller.
14600            if (sender != null) {
14601                if (!(sender instanceof PendingIntentRecord)) {
14602                    return;
14603                }
14604
14605                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14606                final int callerUid = Binder.getCallingUid();
14607                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14608            } else {
14609                // TODO(narayan): Should we throw an exception in this case ? It means that we
14610                // haven't been able to derive a UID to attribute things to.
14611                return;
14612            }
14613        }
14614
14615        if (DEBUG_POWER) {
14616            Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
14617                    + ", workSource=" + workSource + ", tag=" + tag + "]");
14618        }
14619
14620        mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
14621    }
14622
14623    @Override
14624    public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
14625            String tag) {
14626        if (workSource != null && workSource.isEmpty()) {
14627            workSource = null;
14628        }
14629
14630        if (sourceUid <= 0 && workSource == null) {
14631            // Try and derive a UID to attribute things to based on the caller.
14632            if (sender != null) {
14633                if (!(sender instanceof PendingIntentRecord)) {
14634                    return;
14635                }
14636
14637                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14638                final int callerUid = Binder.getCallingUid();
14639                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14640            } else {
14641                // TODO(narayan): Should we throw an exception in this case ? It means that we
14642                // haven't been able to derive a UID to attribute things to.
14643                return;
14644            }
14645        }
14646
14647        if (DEBUG_POWER) {
14648            Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
14649                    ", tag=" + tag + "]");
14650        }
14651
14652        mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
14653    }
14654
14655    @Override
14656    public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
14657            String tag) {
14658        if (workSource != null && workSource.isEmpty()) {
14659            workSource = null;
14660        }
14661
14662        if (sourceUid <= 0 && workSource == null) {
14663            // Try and derive a UID to attribute things to based on the caller.
14664            if (sender != null) {
14665                if (!(sender instanceof PendingIntentRecord)) {
14666                    return;
14667                }
14668
14669                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14670                final int callerUid = Binder.getCallingUid();
14671                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14672            } else {
14673                // TODO(narayan): Should we throw an exception in this case ? It means that we
14674                // haven't been able to derive a UID to attribute things to.
14675                return;
14676            }
14677        }
14678
14679        if (DEBUG_POWER) {
14680            Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
14681                    ", tag=" + tag + "]");
14682        }
14683
14684        mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
14685    }
14686
14687    public boolean killPids(int[] pids, String pReason, boolean secure) {
14688        if (Binder.getCallingUid() != SYSTEM_UID) {
14689            throw new SecurityException("killPids only available to the system");
14690        }
14691        String reason = (pReason == null) ? "Unknown" : pReason;
14692        // XXX Note: don't acquire main activity lock here, because the window
14693        // manager calls in with its locks held.
14694
14695        boolean killed = false;
14696        synchronized (mPidsSelfLocked) {
14697            int worstType = 0;
14698            for (int i=0; i<pids.length; i++) {
14699                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14700                if (proc != null) {
14701                    int type = proc.setAdj;
14702                    if (type > worstType) {
14703                        worstType = type;
14704                    }
14705                }
14706            }
14707
14708            // If the worst oom_adj is somewhere in the cached proc LRU range,
14709            // then constrain it so we will kill all cached procs.
14710            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
14711                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
14712                worstType = ProcessList.CACHED_APP_MIN_ADJ;
14713            }
14714
14715            // If this is not a secure call, don't let it kill processes that
14716            // are important.
14717            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
14718                worstType = ProcessList.SERVICE_ADJ;
14719            }
14720
14721            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
14722            for (int i=0; i<pids.length; i++) {
14723                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14724                if (proc == null) {
14725                    continue;
14726                }
14727                int adj = proc.setAdj;
14728                if (adj >= worstType && !proc.killedByAm) {
14729                    proc.kill(reason, true);
14730                    killed = true;
14731                }
14732            }
14733        }
14734        return killed;
14735    }
14736
14737    @Override
14738    public void killUid(int appId, int userId, String reason) {
14739        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
14740        synchronized (this) {
14741            final long identity = Binder.clearCallingIdentity();
14742            try {
14743                killPackageProcessesLocked(null, appId, userId,
14744                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
14745                        reason != null ? reason : "kill uid");
14746            } finally {
14747                Binder.restoreCallingIdentity(identity);
14748            }
14749        }
14750    }
14751
14752    @Override
14753    public boolean killProcessesBelowForeground(String reason) {
14754        if (Binder.getCallingUid() != SYSTEM_UID) {
14755            throw new SecurityException("killProcessesBelowForeground() only available to system");
14756        }
14757
14758        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
14759    }
14760
14761    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
14762        if (Binder.getCallingUid() != SYSTEM_UID) {
14763            throw new SecurityException("killProcessesBelowAdj() only available to system");
14764        }
14765
14766        boolean killed = false;
14767        synchronized (mPidsSelfLocked) {
14768            final int size = mPidsSelfLocked.size();
14769            for (int i = 0; i < size; i++) {
14770                final int pid = mPidsSelfLocked.keyAt(i);
14771                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14772                if (proc == null) continue;
14773
14774                final int adj = proc.setAdj;
14775                if (adj > belowAdj && !proc.killedByAm) {
14776                    proc.kill(reason, true);
14777                    killed = true;
14778                }
14779            }
14780        }
14781        return killed;
14782    }
14783
14784    @Override
14785    public void hang(final IBinder who, boolean allowRestart) {
14786        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14787                != PackageManager.PERMISSION_GRANTED) {
14788            throw new SecurityException("Requires permission "
14789                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14790        }
14791
14792        final IBinder.DeathRecipient death = new DeathRecipient() {
14793            @Override
14794            public void binderDied() {
14795                synchronized (this) {
14796                    notifyAll();
14797                }
14798            }
14799        };
14800
14801        try {
14802            who.linkToDeath(death, 0);
14803        } catch (RemoteException e) {
14804            Slog.w(TAG, "hang: given caller IBinder is already dead.");
14805            return;
14806        }
14807
14808        synchronized (this) {
14809            Watchdog.getInstance().setAllowRestart(allowRestart);
14810            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
14811            synchronized (death) {
14812                while (who.isBinderAlive()) {
14813                    try {
14814                        death.wait();
14815                    } catch (InterruptedException e) {
14816                    }
14817                }
14818            }
14819            Watchdog.getInstance().setAllowRestart(true);
14820        }
14821    }
14822
14823    @Override
14824    public void restart() {
14825        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14826                != PackageManager.PERMISSION_GRANTED) {
14827            throw new SecurityException("Requires permission "
14828                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14829        }
14830
14831        Log.i(TAG, "Sending shutdown broadcast...");
14832
14833        BroadcastReceiver br = new BroadcastReceiver() {
14834            @Override public void onReceive(Context context, Intent intent) {
14835                // Now the broadcast is done, finish up the low-level shutdown.
14836                Log.i(TAG, "Shutting down activity manager...");
14837                shutdown(10000);
14838                Log.i(TAG, "Shutdown complete, restarting!");
14839                killProcess(myPid());
14840                System.exit(10);
14841            }
14842        };
14843
14844        // First send the high-level shut down broadcast.
14845        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14846        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14847        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
14848        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
14849        mContext.sendOrderedBroadcastAsUser(intent,
14850                UserHandle.ALL, null, br, mHandler, 0, null, null);
14851        */
14852        br.onReceive(mContext, intent);
14853    }
14854
14855    private long getLowRamTimeSinceIdle(long now) {
14856        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
14857    }
14858
14859    @Override
14860    public void performIdleMaintenance() {
14861        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14862                != PackageManager.PERMISSION_GRANTED) {
14863            throw new SecurityException("Requires permission "
14864                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14865        }
14866
14867        synchronized (this) {
14868            final long now = SystemClock.uptimeMillis();
14869            final long timeSinceLastIdle = now - mLastIdleTime;
14870            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
14871            mLastIdleTime = now;
14872            mLowRamTimeSinceLastIdle = 0;
14873            if (mLowRamStartTime != 0) {
14874                mLowRamStartTime = now;
14875            }
14876
14877            StringBuilder sb = new StringBuilder(128);
14878            sb.append("Idle maintenance over ");
14879            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14880            sb.append(" low RAM for ");
14881            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14882            Slog.i(TAG, sb.toString());
14883
14884            // If at least 1/3 of our time since the last idle period has been spent
14885            // with RAM low, then we want to kill processes.
14886            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14887
14888            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14889                ProcessRecord proc = mLruProcesses.get(i);
14890                if (proc.notCachedSinceIdle) {
14891                    if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
14892                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14893                        if (doKilling && proc.initialIdlePss != 0
14894                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14895                            sb = new StringBuilder(128);
14896                            sb.append("Kill");
14897                            sb.append(proc.processName);
14898                            sb.append(" in idle maint: pss=");
14899                            sb.append(proc.lastPss);
14900                            sb.append(", swapPss=");
14901                            sb.append(proc.lastSwapPss);
14902                            sb.append(", initialPss=");
14903                            sb.append(proc.initialIdlePss);
14904                            sb.append(", period=");
14905                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14906                            sb.append(", lowRamPeriod=");
14907                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14908                            Slog.wtfQuiet(TAG, sb.toString());
14909                            proc.kill("idle maint (pss " + proc.lastPss
14910                                    + " from " + proc.initialIdlePss + ")", true);
14911                        }
14912                    }
14913                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14914                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14915                    proc.notCachedSinceIdle = true;
14916                    proc.initialIdlePss = 0;
14917                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null,
14918                            mTestPssMode, isSleepingLocked(), now);
14919                }
14920            }
14921        }
14922    }
14923
14924    @Override
14925    public void sendIdleJobTrigger() {
14926        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14927                != PackageManager.PERMISSION_GRANTED) {
14928            throw new SecurityException("Requires permission "
14929                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14930        }
14931
14932        final long ident = Binder.clearCallingIdentity();
14933        try {
14934            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14935                    .setPackage("android")
14936                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14937            broadcastIntent(null, intent, null, null, 0, null, null, null,
14938                    OP_NONE, null, false, false, UserHandle.USER_ALL);
14939        } finally {
14940            Binder.restoreCallingIdentity(ident);
14941        }
14942    }
14943
14944    private void retrieveSettings() {
14945        final ContentResolver resolver = mContext.getContentResolver();
14946        final boolean freeformWindowManagement =
14947                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14948                        || Settings.Global.getInt(
14949                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14950
14951        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14952        final boolean supportsPictureInPicture = supportsMultiWindow &&
14953                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14954        final boolean supportsSplitScreenMultiWindow =
14955                ActivityManager.supportsSplitScreenMultiWindow(mContext);
14956        final boolean supportsMultiDisplay = mContext.getPackageManager()
14957                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14958        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14959        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14960        final boolean alwaysFinishActivities =
14961                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14962        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14963        final boolean forceResizable = Settings.Global.getInt(
14964                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14965        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14966                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14967        final boolean supportsLeanbackOnly =
14968                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14969        mHiddenApiBlacklist.registerObserver();
14970
14971        // Transfer any global setting for forcing RTL layout, into a System Property
14972        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14973
14974        final Configuration configuration = new Configuration();
14975        Settings.System.getConfiguration(resolver, configuration);
14976        if (forceRtl) {
14977            // This will take care of setting the correct layout direction flags
14978            configuration.setLayoutDirection(configuration.locale);
14979        }
14980
14981        synchronized (this) {
14982            mDebugApp = mOrigDebugApp = debugApp;
14983            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14984            mAlwaysFinishActivities = alwaysFinishActivities;
14985            mSupportsLeanbackOnly = supportsLeanbackOnly;
14986            mForceResizableActivities = forceResizable;
14987            final boolean multiWindowFormEnabled = freeformWindowManagement
14988                    || supportsSplitScreenMultiWindow
14989                    || supportsPictureInPicture
14990                    || supportsMultiDisplay;
14991            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14992                mSupportsMultiWindow = true;
14993                mSupportsFreeformWindowManagement = freeformWindowManagement;
14994                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14995                mSupportsPictureInPicture = supportsPictureInPicture;
14996                mSupportsMultiDisplay = supportsMultiDisplay;
14997            } else {
14998                mSupportsMultiWindow = false;
14999                mSupportsFreeformWindowManagement = false;
15000                mSupportsSplitScreenMultiWindow = false;
15001                mSupportsPictureInPicture = false;
15002                mSupportsMultiDisplay = false;
15003            }
15004            mWindowManager.setForceResizableTasks(mForceResizableActivities);
15005            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
15006            // This happens before any activities are started, so we can change global configuration
15007            // in-place.
15008            updateConfigurationLocked(configuration, null, true);
15009            final Configuration globalConfig = getGlobalConfiguration();
15010            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
15011
15012            // Load resources only after the current configuration has been set.
15013            final Resources res = mContext.getResources();
15014            mThumbnailWidth = res.getDimensionPixelSize(
15015                    com.android.internal.R.dimen.thumbnail_width);
15016            mThumbnailHeight = res.getDimensionPixelSize(
15017                    com.android.internal.R.dimen.thumbnail_height);
15018            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
15019                    com.android.internal.R.string.config_appsNotReportingCrashes));
15020            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
15021                    com.android.internal.R.bool.config_customUserSwitchUi);
15022            mUserController.mMaxRunningUsers = res.getInteger(
15023                    com.android.internal.R.integer.config_multiuserMaxRunningUsers);
15024
15025            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
15026                mFullscreenThumbnailScale = (float) res
15027                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
15028                    (float) globalConfig.screenWidthDp;
15029            } else {
15030                mFullscreenThumbnailScale = res.getFraction(
15031                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
15032            }
15033            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
15034        }
15035    }
15036
15037    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
15038        traceLog.traceBegin("PhaseActivityManagerReady");
15039        synchronized(this) {
15040            if (mSystemReady) {
15041                // If we're done calling all the receivers, run the next "boot phase" passed in
15042                // by the SystemServer
15043                if (goingCallback != null) {
15044                    goingCallback.run();
15045                }
15046                return;
15047            }
15048
15049            mLocalDeviceIdleController
15050                    = LocalServices.getService(DeviceIdleController.LocalService.class);
15051            mAssistUtils = new AssistUtils(mContext);
15052            mVrController.onSystemReady();
15053            // Make sure we have the current profile info, since it is needed for security checks.
15054            mUserController.onSystemReady();
15055            mRecentTasks.onSystemReadyLocked();
15056            mAppOpsService.systemReady();
15057            mSystemReady = true;
15058        }
15059
15060        try {
15061            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
15062                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
15063                    .getSerial();
15064        } catch (RemoteException e) {}
15065
15066        ArrayList<ProcessRecord> procsToKill = null;
15067        synchronized(mPidsSelfLocked) {
15068            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
15069                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
15070                if (!isAllowedWhileBooting(proc.info)){
15071                    if (procsToKill == null) {
15072                        procsToKill = new ArrayList<ProcessRecord>();
15073                    }
15074                    procsToKill.add(proc);
15075                }
15076            }
15077        }
15078
15079        synchronized(this) {
15080            if (procsToKill != null) {
15081                for (int i=procsToKill.size()-1; i>=0; i--) {
15082                    ProcessRecord proc = procsToKill.get(i);
15083                    Slog.i(TAG, "Removing system update proc: " + proc);
15084                    removeProcessLocked(proc, true, false, "system update done");
15085                }
15086            }
15087
15088            // Now that we have cleaned up any update processes, we
15089            // are ready to start launching real processes and know that
15090            // we won't trample on them any more.
15091            mProcessesReady = true;
15092        }
15093
15094        Slog.i(TAG, "System now ready");
15095        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
15096            SystemClock.uptimeMillis());
15097
15098        synchronized(this) {
15099            // Make sure we have no pre-ready processes sitting around.
15100
15101            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
15102                ResolveInfo ri = mContext.getPackageManager()
15103                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
15104                                STOCK_PM_FLAGS);
15105                CharSequence errorMsg = null;
15106                if (ri != null) {
15107                    ActivityInfo ai = ri.activityInfo;
15108                    ApplicationInfo app = ai.applicationInfo;
15109                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
15110                        mTopAction = Intent.ACTION_FACTORY_TEST;
15111                        mTopData = null;
15112                        mTopComponent = new ComponentName(app.packageName,
15113                                ai.name);
15114                    } else {
15115                        errorMsg = mContext.getResources().getText(
15116                                com.android.internal.R.string.factorytest_not_system);
15117                    }
15118                } else {
15119                    errorMsg = mContext.getResources().getText(
15120                            com.android.internal.R.string.factorytest_no_action);
15121                }
15122                if (errorMsg != null) {
15123                    mTopAction = null;
15124                    mTopData = null;
15125                    mTopComponent = null;
15126                    Message msg = Message.obtain();
15127                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
15128                    msg.getData().putCharSequence("msg", errorMsg);
15129                    mUiHandler.sendMessage(msg);
15130                }
15131            }
15132        }
15133
15134        retrieveSettings();
15135        final int currentUserId = mUserController.getCurrentUserId();
15136        synchronized (this) {
15137            readGrantedUriPermissionsLocked();
15138        }
15139
15140        final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
15141        if (pmi != null) {
15142            pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
15143                    state -> updateForceBackgroundCheck(state.batterySaverEnabled));
15144            updateForceBackgroundCheck(
15145                    pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
15146        } else {
15147            Slog.wtf(TAG, "PowerManagerInternal not found.");
15148        }
15149
15150        if (goingCallback != null) goingCallback.run();
15151        traceLog.traceBegin("ActivityManagerStartApps");
15152        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
15153                Integer.toString(currentUserId), currentUserId);
15154        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
15155                Integer.toString(currentUserId), currentUserId);
15156        mSystemServiceManager.startUser(currentUserId);
15157
15158        synchronized (this) {
15159            // Only start up encryption-aware persistent apps; once user is
15160            // unlocked we'll come back around and start unaware apps
15161            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
15162
15163            // Start up initial activity.
15164            mBooting = true;
15165            // Enable home activity for system user, so that the system can always boot. We don't
15166            // do this when the system user is not setup since the setup wizard should be the one
15167            // to handle home activity in this case.
15168            if (UserManager.isSplitSystemUser() &&
15169                    Settings.Secure.getInt(mContext.getContentResolver(),
15170                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
15171                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
15172                try {
15173                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
15174                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
15175                            UserHandle.USER_SYSTEM);
15176                } catch (RemoteException e) {
15177                    throw e.rethrowAsRuntimeException();
15178                }
15179            }
15180            startHomeActivityLocked(currentUserId, "systemReady");
15181
15182            try {
15183                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
15184                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
15185                            + " data partition or your device will be unstable.");
15186                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
15187                }
15188            } catch (RemoteException e) {
15189            }
15190
15191            if (!Build.isBuildConsistent()) {
15192                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
15193                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
15194            }
15195
15196            long ident = Binder.clearCallingIdentity();
15197            try {
15198                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
15199                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15200                        | Intent.FLAG_RECEIVER_FOREGROUND);
15201                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
15202                broadcastIntentLocked(null, null, intent,
15203                        null, null, 0, null, null, null, OP_NONE,
15204                        null, false, false, MY_PID, SYSTEM_UID,
15205                        currentUserId);
15206                intent = new Intent(Intent.ACTION_USER_STARTING);
15207                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15208                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
15209                broadcastIntentLocked(null, null, intent,
15210                        null, new IIntentReceiver.Stub() {
15211                            @Override
15212                            public void performReceive(Intent intent, int resultCode, String data,
15213                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
15214                                    throws RemoteException {
15215                            }
15216                        }, 0, null, null,
15217                        new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
15218                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
15219            } catch (Throwable t) {
15220                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
15221            } finally {
15222                Binder.restoreCallingIdentity(ident);
15223            }
15224            mStackSupervisor.resumeFocusedStackTopActivityLocked();
15225            mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
15226
15227            BinderInternal.nSetBinderProxyCountEnabled(true);
15228            BinderInternal.setBinderProxyCountCallback(
15229                    new BinderInternal.BinderProxyLimitListener() {
15230                        @Override
15231                        public void onLimitReached(int uid) {
15232                            Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
15233                                    + Process.myUid());
15234                            if (uid == Process.SYSTEM_UID) {
15235                                Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
15236                            } else {
15237                                killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
15238                                        "Too many Binders sent to SYSTEM");
15239                            }
15240                        }
15241                    }, mHandler);
15242
15243            traceLog.traceEnd(); // ActivityManagerStartApps
15244            traceLog.traceEnd(); // PhaseActivityManagerReady
15245        }
15246    }
15247
15248    private void updateForceBackgroundCheck(boolean enabled) {
15249        synchronized (this) {
15250            if (mForceBackgroundCheck != enabled) {
15251                mForceBackgroundCheck = enabled;
15252
15253                if (DEBUG_BACKGROUND_CHECK) {
15254                    Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
15255                }
15256
15257                if (mForceBackgroundCheck) {
15258                    // Stop background services for idle UIDs.
15259                    doStopUidForIdleUidsLocked();
15260                }
15261            }
15262        }
15263    }
15264
15265    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
15266        synchronized (this) {
15267            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
15268        }
15269    }
15270
15271    void skipCurrentReceiverLocked(ProcessRecord app) {
15272        for (BroadcastQueue queue : mBroadcastQueues) {
15273            queue.skipCurrentReceiverLocked(app);
15274        }
15275    }
15276
15277    /**
15278     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
15279     * The application process will exit immediately after this call returns.
15280     * @param app object of the crashing app, null for the system server
15281     * @param crashInfo describing the exception
15282     */
15283    public void handleApplicationCrash(IBinder app,
15284            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15285        ProcessRecord r = findAppProcess(app, "Crash");
15286        final String processName = app == null ? "system_server"
15287                : (r == null ? "unknown" : r.processName);
15288
15289        handleApplicationCrashInner("crash", r, processName, crashInfo);
15290    }
15291
15292    /* Native crash reporting uses this inner version because it needs to be somewhat
15293     * decoupled from the AM-managed cleanup lifecycle
15294     */
15295    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
15296            ApplicationErrorReport.CrashInfo crashInfo) {
15297        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
15298                UserHandle.getUserId(Binder.getCallingUid()), processName,
15299                r == null ? -1 : r.info.flags,
15300                crashInfo.exceptionClassName,
15301                crashInfo.exceptionMessage,
15302                crashInfo.throwFileName,
15303                crashInfo.throwLineNumber);
15304
15305        StatsLog.write(StatsLog.APP_CRASH_OCCURRED,
15306                Binder.getCallingUid(),
15307                eventType,
15308                processName,
15309                Binder.getCallingPid(),
15310                (r != null && r.info != null) ? r.info.packageName : "",
15311                (r != null && r.info != null) ? (r.info.isInstantApp()
15312                        ? StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__TRUE
15313                        : StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__FALSE)
15314                        : StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__UNAVAILABLE,
15315                r != null ? (r.isInterestingToUserLocked()
15316                        ? StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__FOREGROUND
15317                        : StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__BACKGROUND)
15318                        : StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__UNKNOWN
15319        );
15320
15321        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
15322
15323        mAppErrors.crashApplication(r, crashInfo);
15324    }
15325
15326    public void handleApplicationStrictModeViolation(
15327            IBinder app,
15328            int violationMask,
15329            StrictMode.ViolationInfo info) {
15330        // We're okay if the ProcessRecord is missing; it probably means that
15331        // we're reporting a violation from the system process itself.
15332        final ProcessRecord r = findAppProcess(app, "StrictMode");
15333
15334        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
15335            Integer stackFingerprint = info.hashCode();
15336            boolean logIt = true;
15337            synchronized (mAlreadyLoggedViolatedStacks) {
15338                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
15339                    logIt = false;
15340                    // TODO: sub-sample into EventLog for these, with
15341                    // the info.durationMillis?  Then we'd get
15342                    // the relative pain numbers, without logging all
15343                    // the stack traces repeatedly.  We'd want to do
15344                    // likewise in the client code, which also does
15345                    // dup suppression, before the Binder call.
15346                } else {
15347                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
15348                        mAlreadyLoggedViolatedStacks.clear();
15349                    }
15350                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
15351                }
15352            }
15353            if (logIt) {
15354                logStrictModeViolationToDropBox(r, info);
15355            }
15356        }
15357
15358        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
15359            AppErrorResult result = new AppErrorResult();
15360            synchronized (this) {
15361                final long origId = Binder.clearCallingIdentity();
15362
15363                Message msg = Message.obtain();
15364                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
15365                HashMap<String, Object> data = new HashMap<String, Object>();
15366                data.put("result", result);
15367                data.put("app", r);
15368                data.put("violationMask", violationMask);
15369                data.put("info", info);
15370                msg.obj = data;
15371                mUiHandler.sendMessage(msg);
15372
15373                Binder.restoreCallingIdentity(origId);
15374            }
15375            int res = result.get();
15376            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
15377        }
15378    }
15379
15380    // Depending on the policy in effect, there could be a bunch of
15381    // these in quick succession so we try to batch these together to
15382    // minimize disk writes, number of dropbox entries, and maximize
15383    // compression, by having more fewer, larger records.
15384    private void logStrictModeViolationToDropBox(
15385            ProcessRecord process,
15386            StrictMode.ViolationInfo info) {
15387        if (info == null) {
15388            return;
15389        }
15390        final boolean isSystemApp = process == null ||
15391                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
15392                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
15393        final String processName = process == null ? "unknown" : process.processName;
15394        final DropBoxManager dbox = (DropBoxManager)
15395                mContext.getSystemService(Context.DROPBOX_SERVICE);
15396
15397        // Exit early if the dropbox isn't configured to accept this report type.
15398        final String dropboxTag = processClass(process) + "_strictmode";
15399        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15400
15401        final StringBuilder sb = new StringBuilder(1024);
15402        synchronized (sb) {
15403            appendDropBoxProcessHeaders(process, processName, sb);
15404            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15405            sb.append("System-App: ").append(isSystemApp).append("\n");
15406            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
15407            if (info.violationNumThisLoop != 0) {
15408                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
15409            }
15410            if (info.numAnimationsRunning != 0) {
15411                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
15412            }
15413            if (info.broadcastIntentAction != null) {
15414                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
15415            }
15416            if (info.durationMillis != -1) {
15417                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
15418            }
15419            if (info.numInstances != -1) {
15420                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
15421            }
15422            if (info.tags != null) {
15423                for (String tag : info.tags) {
15424                    sb.append("Span-Tag: ").append(tag).append("\n");
15425                }
15426            }
15427            sb.append("\n");
15428            sb.append(info.getStackTrace());
15429            sb.append("\n");
15430            if (info.getViolationDetails() != null) {
15431                sb.append(info.getViolationDetails());
15432                sb.append("\n");
15433            }
15434        }
15435
15436        final String res = sb.toString();
15437        IoThread.getHandler().post(() -> {
15438            dbox.addText(dropboxTag, res);
15439        });
15440    }
15441
15442    /**
15443     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
15444     * @param app object of the crashing app, null for the system server
15445     * @param tag reported by the caller
15446     * @param system whether this wtf is coming from the system
15447     * @param crashInfo describing the context of the error
15448     * @return true if the process should exit immediately (WTF is fatal)
15449     */
15450    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
15451            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15452        final int callingUid = Binder.getCallingUid();
15453        final int callingPid = Binder.getCallingPid();
15454
15455        if (system) {
15456            // If this is coming from the system, we could very well have low-level
15457            // system locks held, so we want to do this all asynchronously.  And we
15458            // never want this to become fatal, so there is that too.
15459            mHandler.post(new Runnable() {
15460                @Override public void run() {
15461                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
15462                }
15463            });
15464            return false;
15465        }
15466
15467        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
15468                crashInfo);
15469
15470        final boolean isFatal = Build.IS_ENG || Settings.Global
15471                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
15472        final boolean isSystem = (r == null) || r.persistent;
15473
15474        if (isFatal && !isSystem) {
15475            mAppErrors.crashApplication(r, crashInfo);
15476            return true;
15477        } else {
15478            return false;
15479        }
15480    }
15481
15482    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
15483            final ApplicationErrorReport.CrashInfo crashInfo) {
15484        final ProcessRecord r = findAppProcess(app, "WTF");
15485        final String processName = app == null ? "system_server"
15486                : (r == null ? "unknown" : r.processName);
15487
15488        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
15489                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
15490
15491        StatsLog.write(StatsLog.WTF_OCCURRED, callingUid, tag, processName,
15492                callingPid);
15493
15494        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
15495
15496        return r;
15497    }
15498
15499    /**
15500     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
15501     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
15502     */
15503    private ProcessRecord findAppProcess(IBinder app, String reason) {
15504        if (app == null) {
15505            return null;
15506        }
15507
15508        synchronized (this) {
15509            final int NP = mProcessNames.getMap().size();
15510            for (int ip=0; ip<NP; ip++) {
15511                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
15512                final int NA = apps.size();
15513                for (int ia=0; ia<NA; ia++) {
15514                    ProcessRecord p = apps.valueAt(ia);
15515                    if (p.thread != null && p.thread.asBinder() == app) {
15516                        return p;
15517                    }
15518                }
15519            }
15520
15521            Slog.w(TAG, "Can't find mystery application for " + reason
15522                    + " from pid=" + Binder.getCallingPid()
15523                    + " uid=" + Binder.getCallingUid() + ": " + app);
15524            return null;
15525        }
15526    }
15527
15528    /**
15529     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
15530     * to append various headers to the dropbox log text.
15531     */
15532    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
15533            StringBuilder sb) {
15534        // Watchdog thread ends up invoking this function (with
15535        // a null ProcessRecord) to add the stack file to dropbox.
15536        // Do not acquire a lock on this (am) in such cases, as it
15537        // could cause a potential deadlock, if and when watchdog
15538        // is invoked due to unavailability of lock on am and it
15539        // would prevent watchdog from killing system_server.
15540        if (process == null) {
15541            sb.append("Process: ").append(processName).append("\n");
15542            return;
15543        }
15544        // Note: ProcessRecord 'process' is guarded by the service
15545        // instance.  (notably process.pkgList, which could otherwise change
15546        // concurrently during execution of this method)
15547        synchronized (this) {
15548            sb.append("Process: ").append(processName).append("\n");
15549            sb.append("PID: ").append(process.pid).append("\n");
15550            int flags = process.info.flags;
15551            IPackageManager pm = AppGlobals.getPackageManager();
15552            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
15553            for (int ip=0; ip<process.pkgList.size(); ip++) {
15554                String pkg = process.pkgList.keyAt(ip);
15555                sb.append("Package: ").append(pkg);
15556                try {
15557                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
15558                    if (pi != null) {
15559                        sb.append(" v").append(pi.getLongVersionCode());
15560                        if (pi.versionName != null) {
15561                            sb.append(" (").append(pi.versionName).append(")");
15562                        }
15563                    }
15564                } catch (RemoteException e) {
15565                    Slog.e(TAG, "Error getting package info: " + pkg, e);
15566                }
15567                sb.append("\n");
15568            }
15569            if (process.info.isInstantApp()) {
15570                sb.append("Instant-App: true\n");
15571            }
15572        }
15573    }
15574
15575    private static String processClass(ProcessRecord process) {
15576        if (process == null || process.pid == MY_PID) {
15577            return "system_server";
15578        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15579            return "system_app";
15580        } else {
15581            return "data_app";
15582        }
15583    }
15584
15585    private volatile long mWtfClusterStart;
15586    private volatile int mWtfClusterCount;
15587
15588    /**
15589     * Write a description of an error (crash, WTF, ANR) to the drop box.
15590     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
15591     * @param process which caused the error, null means the system server
15592     * @param activity which triggered the error, null if unknown
15593     * @param parent activity related to the error, null if unknown
15594     * @param subject line related to the error, null if absent
15595     * @param report in long form describing the error, null if absent
15596     * @param dataFile text file to include in the report, null if none
15597     * @param crashInfo giving an application stack trace, null if absent
15598     */
15599    public void addErrorToDropBox(String eventType,
15600            ProcessRecord process, String processName, ActivityRecord activity,
15601            ActivityRecord parent, String subject,
15602            final String report, final File dataFile,
15603            final ApplicationErrorReport.CrashInfo crashInfo) {
15604        // NOTE -- this must never acquire the ActivityManagerService lock,
15605        // otherwise the watchdog may be prevented from resetting the system.
15606
15607        // Bail early if not published yet
15608        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
15609        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
15610
15611        // Exit early if the dropbox isn't configured to accept this report type.
15612        final String dropboxTag = processClass(process) + "_" + eventType;
15613        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15614
15615        // Rate-limit how often we're willing to do the heavy lifting below to
15616        // collect and record logs; currently 5 logs per 10 second period.
15617        final long now = SystemClock.elapsedRealtime();
15618        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
15619            mWtfClusterStart = now;
15620            mWtfClusterCount = 1;
15621        } else {
15622            if (mWtfClusterCount++ >= 5) return;
15623        }
15624
15625        final StringBuilder sb = new StringBuilder(1024);
15626        appendDropBoxProcessHeaders(process, processName, sb);
15627        if (process != null) {
15628            sb.append("Foreground: ")
15629                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
15630                    .append("\n");
15631        }
15632        if (activity != null) {
15633            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
15634        }
15635        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
15636            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
15637        }
15638        if (parent != null && parent != activity) {
15639            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
15640        }
15641        if (subject != null) {
15642            sb.append("Subject: ").append(subject).append("\n");
15643        }
15644        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15645        if (Debug.isDebuggerConnected()) {
15646            sb.append("Debugger: Connected\n");
15647        }
15648        sb.append("\n");
15649
15650        // Do the rest in a worker thread to avoid blocking the caller on I/O
15651        // (After this point, we shouldn't access AMS internal data structures.)
15652        Thread worker = new Thread("Error dump: " + dropboxTag) {
15653            @Override
15654            public void run() {
15655                if (report != null) {
15656                    sb.append(report);
15657                }
15658
15659                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
15660                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
15661                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
15662                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
15663
15664                if (dataFile != null && maxDataFileSize > 0) {
15665                    try {
15666                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
15667                                    "\n\n[[TRUNCATED]]"));
15668                    } catch (IOException e) {
15669                        Slog.e(TAG, "Error reading " + dataFile, e);
15670                    }
15671                }
15672                if (crashInfo != null && crashInfo.stackTrace != null) {
15673                    sb.append(crashInfo.stackTrace);
15674                }
15675
15676                if (lines > 0) {
15677                    sb.append("\n");
15678
15679                    // Merge several logcat streams, and take the last N lines
15680                    InputStreamReader input = null;
15681                    try {
15682                        java.lang.Process logcat = new ProcessBuilder(
15683                                "/system/bin/timeout", "-k", "15s", "10s",
15684                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
15685                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
15686                                        .redirectErrorStream(true).start();
15687
15688                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
15689                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
15690                        input = new InputStreamReader(logcat.getInputStream());
15691
15692                        int num;
15693                        char[] buf = new char[8192];
15694                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
15695                    } catch (IOException e) {
15696                        Slog.e(TAG, "Error running logcat", e);
15697                    } finally {
15698                        if (input != null) try { input.close(); } catch (IOException e) {}
15699                    }
15700                }
15701
15702                dbox.addText(dropboxTag, sb.toString());
15703            }
15704        };
15705
15706        if (process == null) {
15707            // If process is null, we are being called from some internal code
15708            // and may be about to die -- run this synchronously.
15709            final int oldMask = StrictMode.allowThreadDiskWritesMask();
15710            try {
15711                worker.run();
15712            } finally {
15713                StrictMode.setThreadPolicyMask(oldMask);
15714            }
15715        } else {
15716            worker.start();
15717        }
15718    }
15719
15720    @Override
15721    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
15722        enforceNotIsolatedCaller("getProcessesInErrorState");
15723        // assume our apps are happy - lazy create the list
15724        List<ActivityManager.ProcessErrorStateInfo> errList = null;
15725
15726        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15727                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
15728        int userId = UserHandle.getUserId(Binder.getCallingUid());
15729
15730        synchronized (this) {
15731
15732            // iterate across all processes
15733            for (int i=mLruProcesses.size()-1; i>=0; i--) {
15734                ProcessRecord app = mLruProcesses.get(i);
15735                if (!allUsers && app.userId != userId) {
15736                    continue;
15737                }
15738                if ((app.thread != null) && (app.crashing || app.notResponding)) {
15739                    // This one's in trouble, so we'll generate a report for it
15740                    // crashes are higher priority (in case there's a crash *and* an anr)
15741                    ActivityManager.ProcessErrorStateInfo report = null;
15742                    if (app.crashing) {
15743                        report = app.crashingReport;
15744                    } else if (app.notResponding) {
15745                        report = app.notRespondingReport;
15746                    }
15747
15748                    if (report != null) {
15749                        if (errList == null) {
15750                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
15751                        }
15752                        errList.add(report);
15753                    } else {
15754                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
15755                                " crashing = " + app.crashing +
15756                                " notResponding = " + app.notResponding);
15757                    }
15758                }
15759            }
15760        }
15761
15762        return errList;
15763    }
15764
15765    static int procStateToImportance(int procState, int memAdj,
15766            ActivityManager.RunningAppProcessInfo currApp,
15767            int clientTargetSdk) {
15768        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
15769                procState, clientTargetSdk);
15770        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
15771            currApp.lru = memAdj;
15772        } else {
15773            currApp.lru = 0;
15774        }
15775        return imp;
15776    }
15777
15778    private void fillInProcMemInfo(ProcessRecord app,
15779            ActivityManager.RunningAppProcessInfo outInfo,
15780            int clientTargetSdk) {
15781        outInfo.pid = app.pid;
15782        outInfo.uid = app.info.uid;
15783        if (mHeavyWeightProcess == app) {
15784            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
15785        }
15786        if (app.persistent) {
15787            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
15788        }
15789        if (app.activities.size() > 0) {
15790            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
15791        }
15792        outInfo.lastTrimLevel = app.trimMemoryLevel;
15793        int adj = app.curAdj;
15794        int procState = app.curProcState;
15795        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
15796        outInfo.importanceReasonCode = app.adjTypeCode;
15797        outInfo.processState = app.curProcState;
15798    }
15799
15800    @Override
15801    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
15802        enforceNotIsolatedCaller("getRunningAppProcesses");
15803
15804        final int callingUid = Binder.getCallingUid();
15805        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15806
15807        // Lazy instantiation of list
15808        List<ActivityManager.RunningAppProcessInfo> runList = null;
15809        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15810                callingUid) == PackageManager.PERMISSION_GRANTED;
15811        final int userId = UserHandle.getUserId(callingUid);
15812        final boolean allUids = isGetTasksAllowed(
15813                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
15814
15815        synchronized (this) {
15816            // Iterate across all processes
15817            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15818                ProcessRecord app = mLruProcesses.get(i);
15819                if ((!allUsers && app.userId != userId)
15820                        || (!allUids && app.uid != callingUid)) {
15821                    continue;
15822                }
15823                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
15824                    // Generate process state info for running application
15825                    ActivityManager.RunningAppProcessInfo currApp =
15826                        new ActivityManager.RunningAppProcessInfo(app.processName,
15827                                app.pid, app.getPackageList());
15828                    fillInProcMemInfo(app, currApp, clientTargetSdk);
15829                    if (app.adjSource instanceof ProcessRecord) {
15830                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
15831                        currApp.importanceReasonImportance =
15832                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
15833                                        app.adjSourceProcState);
15834                    } else if (app.adjSource instanceof ActivityRecord) {
15835                        ActivityRecord r = (ActivityRecord)app.adjSource;
15836                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
15837                    }
15838                    if (app.adjTarget instanceof ComponentName) {
15839                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
15840                    }
15841                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
15842                    //        + " lru=" + currApp.lru);
15843                    if (runList == null) {
15844                        runList = new ArrayList<>();
15845                    }
15846                    runList.add(currApp);
15847                }
15848            }
15849        }
15850        return runList;
15851    }
15852
15853    @Override
15854    public List<ApplicationInfo> getRunningExternalApplications() {
15855        enforceNotIsolatedCaller("getRunningExternalApplications");
15856        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
15857        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
15858        if (runningApps != null && runningApps.size() > 0) {
15859            Set<String> extList = new HashSet<String>();
15860            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
15861                if (app.pkgList != null) {
15862                    for (String pkg : app.pkgList) {
15863                        extList.add(pkg);
15864                    }
15865                }
15866            }
15867            IPackageManager pm = AppGlobals.getPackageManager();
15868            for (String pkg : extList) {
15869                try {
15870                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
15871                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
15872                        retList.add(info);
15873                    }
15874                } catch (RemoteException e) {
15875                }
15876            }
15877        }
15878        return retList;
15879    }
15880
15881    @Override
15882    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15883        enforceNotIsolatedCaller("getMyMemoryState");
15884
15885        final int callingUid = Binder.getCallingUid();
15886        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15887
15888        synchronized (this) {
15889            ProcessRecord proc;
15890            synchronized (mPidsSelfLocked) {
15891                proc = mPidsSelfLocked.get(Binder.getCallingPid());
15892            }
15893            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15894        }
15895    }
15896
15897    @Override
15898    public int getMemoryTrimLevel() {
15899        enforceNotIsolatedCaller("getMyMemoryState");
15900        synchronized (this) {
15901            return mLastMemoryLevel;
15902        }
15903    }
15904
15905    @Override
15906    public void onShellCommand(FileDescriptor in, FileDescriptor out,
15907            FileDescriptor err, String[] args, ShellCallback callback,
15908            ResultReceiver resultReceiver) {
15909        (new ActivityManagerShellCommand(this, false)).exec(
15910                this, in, out, err, args, callback, resultReceiver);
15911    }
15912
15913    SleepToken acquireSleepToken(String tag, int displayId) {
15914        synchronized (this) {
15915            final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15916            updateSleepIfNeededLocked();
15917            return token;
15918        }
15919    }
15920
15921    @Override
15922    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15923        PriorityDump.dump(mPriorityDumper, fd, pw, args);
15924    }
15925
15926    /**
15927     * Wrapper function to print out debug data filtered by specified arguments.
15928    */
15929    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
15930        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15931
15932        boolean dumpAll = false;
15933        boolean dumpClient = false;
15934        boolean dumpCheckin = false;
15935        boolean dumpCheckinFormat = false;
15936        boolean dumpNormalPriority = false;
15937        boolean dumpVisibleStacksOnly = false;
15938        boolean dumpFocusedStackOnly = false;
15939        String dumpPackage = null;
15940
15941        int opti = 0;
15942        while (opti < args.length) {
15943            String opt = args[opti];
15944            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15945                break;
15946            }
15947            opti++;
15948            if ("-a".equals(opt)) {
15949                dumpAll = true;
15950            } else if ("-c".equals(opt)) {
15951                dumpClient = true;
15952            } else if ("-v".equals(opt)) {
15953                dumpVisibleStacksOnly = true;
15954            } else if ("-f".equals(opt)) {
15955                dumpFocusedStackOnly = true;
15956            } else if ("-p".equals(opt)) {
15957                if (opti < args.length) {
15958                    dumpPackage = args[opti];
15959                    opti++;
15960                } else {
15961                    pw.println("Error: -p option requires package argument");
15962                    return;
15963                }
15964                dumpClient = true;
15965            } else if ("--checkin".equals(opt)) {
15966                dumpCheckin = dumpCheckinFormat = true;
15967            } else if ("-C".equals(opt)) {
15968                dumpCheckinFormat = true;
15969            } else if ("--normal-priority".equals(opt)) {
15970                dumpNormalPriority = true;
15971            } else if ("-h".equals(opt)) {
15972                ActivityManagerShellCommand.dumpHelp(pw, true);
15973                return;
15974            } else {
15975                pw.println("Unknown argument: " + opt + "; use -h for help");
15976            }
15977        }
15978
15979        long origId = Binder.clearCallingIdentity();
15980
15981        if (useProto) {
15982            final ProtoOutputStream proto = new ProtoOutputStream(fd);
15983            String cmd = opti < args.length ? args[opti] : "";
15984            opti++;
15985
15986            if ("activities".equals(cmd) || "a".equals(cmd)) {
15987                // output proto is ActivityManagerServiceDumpActivitiesProto
15988                synchronized (this) {
15989                    writeActivitiesToProtoLocked(proto);
15990                }
15991            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15992                // output proto is ActivityManagerServiceDumpBroadcastsProto
15993                synchronized (this) {
15994                    writeBroadcastsToProtoLocked(proto);
15995                }
15996            } else if ("provider".equals(cmd)) {
15997                String[] newArgs;
15998                String name;
15999                if (opti >= args.length) {
16000                    name = null;
16001                    newArgs = EMPTY_STRING_ARRAY;
16002                } else {
16003                    name = args[opti];
16004                    opti++;
16005                    newArgs = new String[args.length - opti];
16006                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16007                            args.length - opti);
16008                }
16009                if (!dumpProviderProto(fd, pw, name, newArgs)) {
16010                    pw.println("No providers match: " + name);
16011                    pw.println("Use -h for help.");
16012                }
16013            } else if ("service".equals(cmd)) {
16014                // output proto is ActivityManagerServiceDumpServicesProto
16015                mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
16016            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
16017                if (opti < args.length) {
16018                    dumpPackage = args[opti];
16019                    opti++;
16020                }
16021                // output proto is ProcessProto
16022                synchronized (this) {
16023                    writeProcessesToProtoLocked(proto, dumpPackage);
16024                }
16025            } else {
16026                // default option, dump everything, output is ActivityManagerServiceProto
16027                synchronized (this) {
16028                    long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
16029                    writeActivitiesToProtoLocked(proto);
16030                    proto.end(activityToken);
16031
16032                    long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
16033                    writeBroadcastsToProtoLocked(proto);
16034                    proto.end(broadcastToken);
16035
16036                    long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
16037                    mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
16038                    proto.end(serviceToken);
16039
16040                    long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
16041                    writeProcessesToProtoLocked(proto, dumpPackage);
16042                    proto.end(processToken);
16043                }
16044            }
16045            proto.flush();
16046            Binder.restoreCallingIdentity(origId);
16047            return;
16048        }
16049
16050        int dumpAppId = getAppId(dumpPackage);
16051        boolean more = false;
16052        // Is the caller requesting to dump a particular piece of data?
16053        if (opti < args.length) {
16054            String cmd = args[opti];
16055            opti++;
16056            if ("activities".equals(cmd) || "a".equals(cmd)) {
16057                synchronized (this) {
16058                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
16059                }
16060            } else if ("lastanr".equals(cmd)) {
16061                synchronized (this) {
16062                    dumpLastANRLocked(pw);
16063                }
16064            } else if ("starter".equals(cmd)) {
16065                synchronized (this) {
16066                    dumpActivityStarterLocked(pw, dumpPackage);
16067                }
16068            } else if ("containers".equals(cmd)) {
16069                synchronized (this) {
16070                    dumpActivityContainersLocked(pw);
16071                }
16072            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
16073                synchronized (this) {
16074                    if (mRecentTasks != null) {
16075                        mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
16076                    }
16077                }
16078            } else if ("binder-proxies".equals(cmd)) {
16079                if (opti >= args.length) {
16080                    dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
16081                            "Counts of Binder Proxies held by SYSTEM");
16082                } else {
16083                    String uid = args[opti];
16084                    opti++;
16085                    // Ensure Binder Proxy Count is as up to date as possible
16086                    System.gc();
16087                    System.runFinalization();
16088                    System.gc();
16089                    pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
16090                }
16091            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
16092                if (opti < args.length) {
16093                    dumpPackage = args[opti];
16094                    opti++;
16095                }
16096                synchronized (this) {
16097                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
16098                }
16099            } else if ("broadcast-stats".equals(cmd)) {
16100                if (opti < args.length) {
16101                    dumpPackage = args[opti];
16102                    opti++;
16103                }
16104                synchronized (this) {
16105                    if (dumpCheckinFormat) {
16106                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
16107                                dumpPackage);
16108                    } else {
16109                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
16110                    }
16111                }
16112            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
16113                if (opti < args.length) {
16114                    dumpPackage = args[opti];
16115                    opti++;
16116                }
16117                synchronized (this) {
16118                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
16119                }
16120            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
16121                if (opti < args.length) {
16122                    dumpPackage = args[opti];
16123                    opti++;
16124                }
16125                synchronized (this) {
16126                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
16127                }
16128            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
16129                synchronized (this) {
16130                    dumpOomLocked(fd, pw, args, opti, true);
16131                }
16132            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
16133                synchronized (this) {
16134                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
16135                }
16136            } else if ("provider".equals(cmd)) {
16137                String[] newArgs;
16138                String name;
16139                if (opti >= args.length) {
16140                    name = null;
16141                    newArgs = EMPTY_STRING_ARRAY;
16142                } else {
16143                    name = args[opti];
16144                    opti++;
16145                    newArgs = new String[args.length - opti];
16146                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16147                }
16148                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
16149                    pw.println("No providers match: " + name);
16150                    pw.println("Use -h for help.");
16151                }
16152            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
16153                synchronized (this) {
16154                    dumpProvidersLocked(fd, pw, args, opti, true, null);
16155                }
16156            } else if ("service".equals(cmd)) {
16157                String[] newArgs;
16158                String name;
16159                if (opti >= args.length) {
16160                    name = null;
16161                    newArgs = EMPTY_STRING_ARRAY;
16162                } else {
16163                    name = args[opti];
16164                    opti++;
16165                    newArgs = new String[args.length - opti];
16166                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16167                            args.length - opti);
16168                }
16169                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
16170                    pw.println("No services match: " + name);
16171                    pw.println("Use -h for help.");
16172                }
16173            } else if ("package".equals(cmd)) {
16174                String[] newArgs;
16175                if (opti >= args.length) {
16176                    pw.println("package: no package name specified");
16177                    pw.println("Use -h for help.");
16178                } else {
16179                    dumpPackage = args[opti];
16180                    opti++;
16181                    newArgs = new String[args.length - opti];
16182                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16183                            args.length - opti);
16184                    args = newArgs;
16185                    opti = 0;
16186                    more = true;
16187                }
16188            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
16189                synchronized (this) {
16190                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
16191                }
16192            } else if ("settings".equals(cmd)) {
16193                synchronized (this) {
16194                    mConstants.dump(pw);
16195                }
16196            } else if ("services".equals(cmd) || "s".equals(cmd)) {
16197                if (dumpClient) {
16198                    ActiveServices.ServiceDumper dumper;
16199                    synchronized (this) {
16200                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16201                                dumpPackage);
16202                    }
16203                    dumper.dumpWithClient();
16204                } else {
16205                    synchronized (this) {
16206                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16207                                dumpPackage).dumpLocked();
16208                    }
16209                }
16210            } else if ("locks".equals(cmd)) {
16211                LockGuard.dump(fd, pw, args);
16212            } else {
16213                // Dumping a single activity?
16214                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
16215                        dumpFocusedStackOnly)) {
16216                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
16217                    int res = shell.exec(this, null, fd, null, args, null,
16218                            new ResultReceiver(null));
16219                    if (res < 0) {
16220                        pw.println("Bad activity command, or no activities match: " + cmd);
16221                        pw.println("Use -h for help.");
16222                    }
16223                }
16224            }
16225            if (!more) {
16226                Binder.restoreCallingIdentity(origId);
16227                return;
16228            }
16229        }
16230
16231        // No piece of data specified, dump everything.
16232        if (dumpCheckinFormat) {
16233            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
16234        } else if (dumpClient) {
16235            ActiveServices.ServiceDumper sdumper;
16236            synchronized (this) {
16237                mConstants.dump(pw);
16238                pw.println();
16239                if (dumpAll) {
16240                    pw.println("-------------------------------------------------------------------------------");
16241                }
16242                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16243                pw.println();
16244                if (dumpAll) {
16245                    pw.println("-------------------------------------------------------------------------------");
16246                }
16247                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16248                pw.println();
16249                if (dumpAll) {
16250                    pw.println("-------------------------------------------------------------------------------");
16251                }
16252                if (dumpAll || dumpPackage != null) {
16253                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16254                    pw.println();
16255                    if (dumpAll) {
16256                        pw.println("-------------------------------------------------------------------------------");
16257                    }
16258                }
16259                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16260                pw.println();
16261                if (dumpAll) {
16262                    pw.println("-------------------------------------------------------------------------------");
16263                }
16264                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16265                pw.println();
16266                if (dumpAll) {
16267                    pw.println("-------------------------------------------------------------------------------");
16268                }
16269                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
16270                        dumpPackage);
16271            }
16272            sdumper.dumpWithClient();
16273            pw.println();
16274            synchronized (this) {
16275                if (dumpAll) {
16276                    pw.println("-------------------------------------------------------------------------------");
16277                }
16278                if (mRecentTasks != null) {
16279                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
16280                }
16281                pw.println();
16282                if (dumpAll) {
16283                    pw.println("-------------------------------------------------------------------------------");
16284                }
16285                dumpLastANRLocked(pw);
16286                pw.println();
16287                if (dumpAll) {
16288                    pw.println("-------------------------------------------------------------------------------");
16289                }
16290                dumpActivityStarterLocked(pw, dumpPackage);
16291                pw.println();
16292                if (dumpAll) {
16293                    pw.println("-------------------------------------------------------------------------------");
16294                }
16295                dumpActivityContainersLocked(pw);
16296                pw.println();
16297                if (dumpAll) {
16298                    pw.println("-------------------------------------------------------------------------------");
16299                }
16300                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16301                if (mAssociations.size() > 0) {
16302                    pw.println();
16303                    if (dumpAll) {
16304                        pw.println("-------------------------------------------------------------------------------");
16305                    }
16306                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16307                }
16308                pw.println();
16309                if (dumpAll) {
16310                    pw.println("-------------------------------------------------------------------------------");
16311                }
16312                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16313            }
16314
16315        } else {
16316            synchronized (this) {
16317                mConstants.dump(pw);
16318                pw.println();
16319                if (dumpAll) {
16320                    pw.println("-------------------------------------------------------------------------------");
16321                }
16322                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16323                pw.println();
16324                if (dumpAll) {
16325                    pw.println("-------------------------------------------------------------------------------");
16326                }
16327                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16328                pw.println();
16329                if (dumpAll) {
16330                    pw.println("-------------------------------------------------------------------------------");
16331                }
16332                if (dumpAll || dumpPackage != null) {
16333                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16334                    pw.println();
16335                    if (dumpAll) {
16336                        pw.println("-------------------------------------------------------------------------------");
16337                    }
16338                }
16339                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16340                pw.println();
16341                if (dumpAll) {
16342                    pw.println("-------------------------------------------------------------------------------");
16343                }
16344                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16345                pw.println();
16346                if (dumpAll) {
16347                    pw.println("-------------------------------------------------------------------------------");
16348                }
16349                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
16350                        .dumpLocked();
16351                pw.println();
16352                if (dumpAll) {
16353                    pw.println("-------------------------------------------------------------------------------");
16354                }
16355                if (mRecentTasks != null) {
16356                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
16357                }
16358                pw.println();
16359                if (dumpAll) {
16360                    pw.println("-------------------------------------------------------------------------------");
16361                }
16362                dumpLastANRLocked(pw);
16363                pw.println();
16364                if (dumpAll) {
16365                    pw.println("-------------------------------------------------------------------------------");
16366                }
16367                dumpActivityStarterLocked(pw, dumpPackage);
16368                pw.println();
16369                if (dumpAll) {
16370                    pw.println("-------------------------------------------------------------------------------");
16371                }
16372                dumpActivityContainersLocked(pw);
16373                // Activities section is dumped as part of the Critical priority dump. Exclude the
16374                // section if priority is Normal.
16375                if (!dumpNormalPriority){
16376                    pw.println();
16377                    if (dumpAll) {
16378                        pw.println("-------------------------------------------------------------------------------");
16379                    }
16380                    dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16381                }
16382                if (mAssociations.size() > 0) {
16383                    pw.println();
16384                    if (dumpAll) {
16385                        pw.println("-------------------------------------------------------------------------------");
16386                    }
16387                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16388                }
16389                pw.println();
16390                if (dumpAll) {
16391                    pw.println("-------------------------------------------------------------------------------");
16392                }
16393                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16394            }
16395        }
16396        Binder.restoreCallingIdentity(origId);
16397    }
16398
16399    private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
16400        // The output proto of "activity --proto activities" is ActivityManagerServiceDumpActivitiesProto
16401        mStackSupervisor.writeToProto(proto, ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
16402    }
16403
16404    private void dumpLastANRLocked(PrintWriter pw) {
16405        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
16406        if (mLastANRState == null) {
16407            pw.println("  <no ANR has occurred since boot>");
16408        } else {
16409            pw.println(mLastANRState);
16410        }
16411    }
16412
16413    private void dumpActivityContainersLocked(PrintWriter pw) {
16414        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
16415        mStackSupervisor.dumpChildrenNames(pw, " ");
16416        pw.println(" ");
16417    }
16418
16419    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
16420        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
16421        mActivityStartController.dump(pw, "", dumpPackage);
16422    }
16423
16424    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16425            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16426        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
16427                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
16428    }
16429
16430    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16431            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
16432        pw.println(header);
16433
16434        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
16435                dumpPackage);
16436        boolean needSep = printedAnything;
16437
16438        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
16439                mStackSupervisor.getResumedActivityLocked(),
16440                dumpPackage, needSep, "  ResumedActivity: ");
16441        if (printed) {
16442            printedAnything = true;
16443            needSep = false;
16444        }
16445
16446        if (dumpPackage == null) {
16447            if (needSep) {
16448                pw.println();
16449            }
16450            printedAnything = true;
16451            mStackSupervisor.dump(pw, "  ");
16452        }
16453
16454        if (!printedAnything) {
16455            pw.println("  (nothing)");
16456        }
16457    }
16458
16459    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16460            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16461        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
16462
16463        int dumpUid = 0;
16464        if (dumpPackage != null) {
16465            IPackageManager pm = AppGlobals.getPackageManager();
16466            try {
16467                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
16468            } catch (RemoteException e) {
16469            }
16470        }
16471
16472        boolean printedAnything = false;
16473
16474        final long now = SystemClock.uptimeMillis();
16475
16476        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
16477            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
16478                    = mAssociations.valueAt(i1);
16479            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
16480                SparseArray<ArrayMap<String, Association>> sourceUids
16481                        = targetComponents.valueAt(i2);
16482                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
16483                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
16484                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
16485                        Association ass = sourceProcesses.valueAt(i4);
16486                        if (dumpPackage != null) {
16487                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
16488                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
16489                                continue;
16490                            }
16491                        }
16492                        printedAnything = true;
16493                        pw.print("  ");
16494                        pw.print(ass.mTargetProcess);
16495                        pw.print("/");
16496                        UserHandle.formatUid(pw, ass.mTargetUid);
16497                        pw.print(" <- ");
16498                        pw.print(ass.mSourceProcess);
16499                        pw.print("/");
16500                        UserHandle.formatUid(pw, ass.mSourceUid);
16501                        pw.println();
16502                        pw.print("    via ");
16503                        pw.print(ass.mTargetComponent.flattenToShortString());
16504                        pw.println();
16505                        pw.print("    ");
16506                        long dur = ass.mTime;
16507                        if (ass.mNesting > 0) {
16508                            dur += now - ass.mStartTime;
16509                        }
16510                        TimeUtils.formatDuration(dur, pw);
16511                        pw.print(" (");
16512                        pw.print(ass.mCount);
16513                        pw.print(" times)");
16514                        pw.print("  ");
16515                        for (int i=0; i<ass.mStateTimes.length; i++) {
16516                            long amt = ass.mStateTimes[i];
16517                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16518                                amt += now - ass.mLastStateUptime;
16519                            }
16520                            if (amt != 0) {
16521                                pw.print(" ");
16522                                pw.print(ProcessList.makeProcStateString(
16523                                            i + ActivityManager.MIN_PROCESS_STATE));
16524                                pw.print("=");
16525                                TimeUtils.formatDuration(amt, pw);
16526                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16527                                    pw.print("*");
16528                                }
16529                            }
16530                        }
16531                        pw.println();
16532                        if (ass.mNesting > 0) {
16533                            pw.print("    Currently active: ");
16534                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
16535                            pw.println();
16536                        }
16537                    }
16538                }
16539            }
16540
16541        }
16542
16543        if (!printedAnything) {
16544            pw.println("  (nothing)");
16545        }
16546    }
16547
16548    private int getAppId(String dumpPackage) {
16549        if (dumpPackage != null) {
16550            try {
16551                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
16552                        dumpPackage, 0);
16553                return UserHandle.getAppId(info.uid);
16554            } catch (NameNotFoundException e) {
16555                e.printStackTrace();
16556            }
16557        }
16558        return -1;
16559    }
16560
16561    boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
16562                String header, boolean needSep) {
16563        boolean printed = false;
16564        for (int i=0; i<uids.size(); i++) {
16565            UidRecord uidRec = uids.valueAt(i);
16566            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
16567                continue;
16568            }
16569            if (!printed) {
16570                printed = true;
16571                if (needSep) {
16572                    pw.println();
16573                }
16574                pw.print("  ");
16575                pw.println(header);
16576                needSep = true;
16577            }
16578            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
16579            pw.print(": "); pw.println(uidRec);
16580        }
16581        return printed;
16582    }
16583
16584    boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
16585        if(counts != null) {
16586            pw.println(header);
16587            for (int i = 0; i < counts.size(); i++) {
16588                final int uid = counts.keyAt(i);
16589                final int binderCount = counts.valueAt(i);
16590                pw.print("    UID ");
16591                pw.print(uid);
16592                pw.print(", binder count = ");
16593                pw.print(binderCount);
16594                pw.print(", package(s)= ");
16595                final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
16596                if (pkgNames != null) {
16597                    for (int j = 0; j < pkgNames.length; j++) {
16598                        pw.print(pkgNames[j]);
16599                        pw.print("; ");
16600                    }
16601                } else {
16602                    pw.print("NO PACKAGE NAME FOUND");
16603                }
16604                pw.println();
16605            }
16606            pw.println();
16607            return true;
16608        }
16609        return false;
16610    }
16611
16612    @GuardedBy("this")
16613    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16614            int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
16615        boolean needSep = false;
16616        int numPers = 0;
16617
16618        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
16619
16620        if (dumpAll) {
16621            final int NP = mProcessNames.getMap().size();
16622            for (int ip=0; ip<NP; ip++) {
16623                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16624                final int NA = procs.size();
16625                for (int ia=0; ia<NA; ia++) {
16626                    ProcessRecord r = procs.valueAt(ia);
16627                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16628                        continue;
16629                    }
16630                    if (!needSep) {
16631                        pw.println("  All known processes:");
16632                        needSep = true;
16633                    }
16634                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
16635                        pw.print(" UID "); pw.print(procs.keyAt(ia));
16636                        pw.print(" "); pw.println(r);
16637                    r.dump(pw, "    ");
16638                    if (r.persistent) {
16639                        numPers++;
16640                    }
16641                }
16642            }
16643        }
16644
16645        if (mIsolatedProcesses.size() > 0) {
16646            boolean printed = false;
16647            for (int i=0; i<mIsolatedProcesses.size(); i++) {
16648                ProcessRecord r = mIsolatedProcesses.valueAt(i);
16649                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16650                    continue;
16651                }
16652                if (!printed) {
16653                    if (needSep) {
16654                        pw.println();
16655                    }
16656                    pw.println("  Isolated process list (sorted by uid):");
16657                    printed = true;
16658                    needSep = true;
16659                }
16660                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
16661                pw.println(r);
16662            }
16663        }
16664
16665        if (mActiveInstrumentation.size() > 0) {
16666            boolean printed = false;
16667            for (int i=0; i<mActiveInstrumentation.size(); i++) {
16668                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16669                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16670                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16671                    continue;
16672                }
16673                if (!printed) {
16674                    if (needSep) {
16675                        pw.println();
16676                    }
16677                    pw.println("  Active instrumentation:");
16678                    printed = true;
16679                    needSep = true;
16680                }
16681                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
16682                pw.println(ai);
16683                ai.dump(pw, "      ");
16684            }
16685        }
16686
16687        if (mActiveUids.size() > 0) {
16688            if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
16689                needSep = true;
16690            }
16691        }
16692        if (dumpAll) {
16693            if (mValidateUids.size() > 0) {
16694                if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
16695                        needSep)) {
16696                    needSep = true;
16697                }
16698            }
16699        }
16700
16701        if (mLruProcesses.size() > 0) {
16702            if (needSep) {
16703                pw.println();
16704            }
16705            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
16706                    pw.print(" total, non-act at ");
16707                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16708                    pw.print(", non-svc at ");
16709                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16710                    pw.println("):");
16711            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
16712            needSep = true;
16713        }
16714
16715        if (dumpAll || dumpPackage != null) {
16716            synchronized (mPidsSelfLocked) {
16717                boolean printed = false;
16718                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16719                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16720                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16721                        continue;
16722                    }
16723                    if (!printed) {
16724                        if (needSep) pw.println();
16725                        needSep = true;
16726                        pw.println("  PID mappings:");
16727                        printed = true;
16728                    }
16729                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
16730                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
16731                }
16732            }
16733        }
16734
16735        if (mImportantProcesses.size() > 0) {
16736            synchronized (mPidsSelfLocked) {
16737                boolean printed = false;
16738                for (int i = 0; i< mImportantProcesses.size(); i++) {
16739                    ProcessRecord r = mPidsSelfLocked.get(
16740                            mImportantProcesses.valueAt(i).pid);
16741                    if (dumpPackage != null && (r == null
16742                            || !r.pkgList.containsKey(dumpPackage))) {
16743                        continue;
16744                    }
16745                    if (!printed) {
16746                        if (needSep) pw.println();
16747                        needSep = true;
16748                        pw.println("  Foreground Processes:");
16749                        printed = true;
16750                    }
16751                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
16752                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
16753                }
16754            }
16755        }
16756
16757        if (mPersistentStartingProcesses.size() > 0) {
16758            if (needSep) pw.println();
16759            needSep = true;
16760            pw.println("  Persisent processes that are starting:");
16761            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
16762                    "Starting Norm", "Restarting PERS", dumpPackage);
16763        }
16764
16765        if (mRemovedProcesses.size() > 0) {
16766            if (needSep) pw.println();
16767            needSep = true;
16768            pw.println("  Processes that are being removed:");
16769            dumpProcessList(pw, this, mRemovedProcesses, "    ",
16770                    "Removed Norm", "Removed PERS", dumpPackage);
16771        }
16772
16773        if (mProcessesOnHold.size() > 0) {
16774            if (needSep) pw.println();
16775            needSep = true;
16776            pw.println("  Processes that are on old until the system is ready:");
16777            dumpProcessList(pw, this, mProcessesOnHold, "    ",
16778                    "OnHold Norm", "OnHold PERS", dumpPackage);
16779        }
16780
16781        needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
16782
16783        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
16784
16785        if (dumpPackage == null) {
16786            pw.println();
16787            needSep = false;
16788            mUserController.dump(pw, dumpAll);
16789        }
16790        if (mHomeProcess != null && (dumpPackage == null
16791                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16792            if (needSep) {
16793                pw.println();
16794                needSep = false;
16795            }
16796            pw.println("  mHomeProcess: " + mHomeProcess);
16797        }
16798        if (mPreviousProcess != null && (dumpPackage == null
16799                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16800            if (needSep) {
16801                pw.println();
16802                needSep = false;
16803            }
16804            pw.println("  mPreviousProcess: " + mPreviousProcess);
16805        }
16806        if (dumpAll && (mPreviousProcess == null || dumpPackage == null
16807                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16808            StringBuilder sb = new StringBuilder(128);
16809            sb.append("  mPreviousProcessVisibleTime: ");
16810            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
16811            pw.println(sb);
16812        }
16813        if (mHeavyWeightProcess != null && (dumpPackage == null
16814                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16815            if (needSep) {
16816                pw.println();
16817                needSep = false;
16818            }
16819            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16820        }
16821        if (dumpAll && mPendingStarts.size() > 0) {
16822            if (needSep) pw.println();
16823            needSep = true;
16824            pw.println("  mPendingStarts: ");
16825            for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
16826                pw.println("    " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
16827            }
16828        }
16829        if (dumpPackage == null) {
16830            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
16831            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
16832        }
16833        if (dumpAll) {
16834            if (dumpPackage == null) {
16835                pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
16836            }
16837            if (mCompatModePackages.getPackages().size() > 0) {
16838                boolean printed = false;
16839                for (Map.Entry<String, Integer> entry
16840                        : mCompatModePackages.getPackages().entrySet()) {
16841                    String pkg = entry.getKey();
16842                    int mode = entry.getValue();
16843                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
16844                        continue;
16845                    }
16846                    if (!printed) {
16847                        pw.println("  mScreenCompatPackages:");
16848                        printed = true;
16849                    }
16850                    pw.print("    "); pw.print(pkg); pw.print(": ");
16851                            pw.print(mode); pw.println();
16852                }
16853            }
16854            final int NI = mUidObservers.getRegisteredCallbackCount();
16855            boolean printed = false;
16856            for (int i=0; i<NI; i++) {
16857                final UidObserverRegistration reg = (UidObserverRegistration)
16858                        mUidObservers.getRegisteredCallbackCookie(i);
16859                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
16860                    if (!printed) {
16861                        pw.println("  mUidObservers:");
16862                        printed = true;
16863                    }
16864                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
16865                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
16866                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
16867                        pw.print(" IDLE");
16868                    }
16869                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
16870                        pw.print(" ACT" );
16871                    }
16872                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
16873                        pw.print(" GONE");
16874                    }
16875                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
16876                        pw.print(" STATE");
16877                        pw.print(" (cut="); pw.print(reg.cutpoint);
16878                        pw.print(")");
16879                    }
16880                    pw.println();
16881                    if (reg.lastProcStates != null) {
16882                        final int NJ = reg.lastProcStates.size();
16883                        for (int j=0; j<NJ; j++) {
16884                            pw.print("      Last ");
16885                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
16886                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
16887                        }
16888                    }
16889                }
16890            }
16891            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
16892            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
16893            if (mPendingTempWhitelist.size() > 0) {
16894                pw.println("  mPendingTempWhitelist:");
16895                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
16896                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
16897                    pw.print("    ");
16898                    UserHandle.formatUid(pw, ptw.targetUid);
16899                    pw.print(": ");
16900                    TimeUtils.formatDuration(ptw.duration, pw);
16901                    pw.print(" ");
16902                    pw.println(ptw.tag);
16903                }
16904            }
16905        }
16906        if (dumpPackage == null) {
16907            pw.println("  mWakefulness="
16908                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
16909            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
16910            pw.println("  mSleeping=" + mSleeping);
16911            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
16912            if (mRunningVoice != null) {
16913                pw.println("  mRunningVoice=" + mRunningVoice);
16914                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
16915            }
16916            pw.println("  mVrController=" + mVrController);
16917        }
16918        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16919                || mOrigWaitForDebugger) {
16920            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16921                    || dumpPackage.equals(mOrigDebugApp)) {
16922                if (needSep) {
16923                    pw.println();
16924                    needSep = false;
16925                }
16926                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
16927                        + " mDebugTransient=" + mDebugTransient
16928                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
16929            }
16930        }
16931        if (mCurAppTimeTracker != null) {
16932            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
16933        }
16934        if (mMemWatchProcesses.getMap().size() > 0) {
16935            pw.println("  Mem watch processes:");
16936            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
16937                    = mMemWatchProcesses.getMap();
16938            for (int i=0; i<procs.size(); i++) {
16939                final String proc = procs.keyAt(i);
16940                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16941                for (int j=0; j<uids.size(); j++) {
16942                    if (needSep) {
16943                        pw.println();
16944                        needSep = false;
16945                    }
16946                    StringBuilder sb = new StringBuilder();
16947                    sb.append("    ").append(proc).append('/');
16948                    UserHandle.formatUid(sb, uids.keyAt(j));
16949                    Pair<Long, String> val = uids.valueAt(j);
16950                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
16951                    if (val.second != null) {
16952                        sb.append(", report to ").append(val.second);
16953                    }
16954                    pw.println(sb.toString());
16955                }
16956            }
16957            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
16958            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
16959            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
16960                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
16961        }
16962        if (mTrackAllocationApp != null) {
16963            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16964                if (needSep) {
16965                    pw.println();
16966                    needSep = false;
16967                }
16968                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
16969            }
16970        }
16971        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16972                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16973            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16974                if (needSep) {
16975                    pw.println();
16976                    needSep = false;
16977                }
16978                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16979                if (mProfilerInfo != null) {
16980                    pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16981                            mProfilerInfo.profileFd);
16982                    pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
16983                            " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16984                            " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16985                    pw.println("  mProfileType=" + mProfileType);
16986                }
16987            }
16988        }
16989        if (mNativeDebuggingApp != null) {
16990            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16991                if (needSep) {
16992                    pw.println();
16993                    needSep = false;
16994                }
16995                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16996            }
16997        }
16998        if (mAllowAppSwitchUids.size() > 0) {
16999            boolean printed = false;
17000            for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
17001                ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
17002                for (int j = 0; j < types.size(); j++) {
17003                    if (dumpPackage == null ||
17004                            UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
17005                        if (needSep) {
17006                            pw.println();
17007                            needSep = false;
17008                        }
17009                        if (!printed) {
17010                            pw.println("  mAllowAppSwitchUids:");
17011                            printed = true;
17012                        }
17013                        pw.print("    User ");
17014                        pw.print(mAllowAppSwitchUids.keyAt(i));
17015                        pw.print(": Type ");
17016                        pw.print(types.keyAt(j));
17017                        pw.print(" = ");
17018                        UserHandle.formatUid(pw, types.valueAt(j).intValue());
17019                        pw.println();
17020                    }
17021                }
17022            }
17023        }
17024        if (dumpPackage == null) {
17025            if (mAlwaysFinishActivities) {
17026                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
17027            }
17028            if (mController != null) {
17029                pw.println("  mController=" + mController
17030                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
17031            }
17032            if (dumpAll) {
17033                pw.println("  Total persistent processes: " + numPers);
17034                pw.println("  mProcessesReady=" + mProcessesReady
17035                        + " mSystemReady=" + mSystemReady
17036                        + " mBooted=" + mBooted
17037                        + " mFactoryTest=" + mFactoryTest);
17038                pw.println("  mBooting=" + mBooting
17039                        + " mCallFinishBooting=" + mCallFinishBooting
17040                        + " mBootAnimationComplete=" + mBootAnimationComplete);
17041                pw.print("  mLastPowerCheckUptime=");
17042                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
17043                        pw.println("");
17044                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
17045                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
17046                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
17047                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
17048                        + " (" + mLruProcesses.size() + " total)"
17049                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
17050                        + " mNumServiceProcs=" + mNumServiceProcs
17051                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
17052                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
17053                        + " mLastMemoryLevel=" + mLastMemoryLevel
17054                        + " mLastNumProcesses=" + mLastNumProcesses);
17055                long now = SystemClock.uptimeMillis();
17056                pw.print("  mLastIdleTime=");
17057                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
17058                        pw.print(" mLowRamSinceLastIdle=");
17059                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
17060                        pw.println();
17061                pw.println();
17062                pw.print("  mUidChangeDispatchCount=");
17063                pw.print(mUidChangeDispatchCount);
17064                pw.println();
17065
17066                pw.println("  Slow UID dispatches:");
17067                final int N = mUidObservers.beginBroadcast();
17068                for (int i = 0; i < N; i++) {
17069                    UidObserverRegistration r =
17070                            (UidObserverRegistration) mUidObservers.getBroadcastCookie(i);
17071                    pw.print("    ");
17072                    pw.print(mUidObservers.getBroadcastItem(i).getClass().getTypeName());
17073                    pw.print(": ");
17074                    pw.print(r.mSlowDispatchCount);
17075                    pw.print(" / Max ");
17076                    pw.print(r.mMaxDispatchTime);
17077                    pw.println("ms");
17078                }
17079                mUidObservers.finishBroadcast();
17080
17081                pw.println();
17082                pw.println("  ServiceManager statistics:");
17083                ServiceManager.sStatLogger.dump(pw, "    ");
17084                pw.println();
17085            }
17086        }
17087        pw.println("  mForceBackgroundCheck=" + mForceBackgroundCheck);
17088    }
17089
17090    @GuardedBy("this")
17091    void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
17092        int numPers = 0;
17093
17094        final int NP = mProcessNames.getMap().size();
17095        for (int ip=0; ip<NP; ip++) {
17096            SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
17097            final int NA = procs.size();
17098            for (int ia = 0; ia<NA; ia++) {
17099                ProcessRecord r = procs.valueAt(ia);
17100                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17101                    continue;
17102                }
17103                r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PROCS);
17104                if (r.persistent) {
17105                    numPers++;
17106                }
17107            }
17108        }
17109
17110        for (int i=0; i<mIsolatedProcesses.size(); i++) {
17111            ProcessRecord r = mIsolatedProcesses.valueAt(i);
17112            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17113                continue;
17114            }
17115            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS);
17116        }
17117
17118        for (int i=0; i<mActiveInstrumentation.size(); i++) {
17119            ActiveInstrumentation ai = mActiveInstrumentation.get(i);
17120            if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
17121                    && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
17122                continue;
17123            }
17124            ai.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_INSTRUMENTATIONS);
17125        }
17126
17127        int whichAppId = getAppId(dumpPackage);
17128        for (int i=0; i<mActiveUids.size(); i++) {
17129            UidRecord uidRec = mActiveUids.valueAt(i);
17130            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
17131                continue;
17132            }
17133            uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
17134        }
17135
17136        for (int i=0; i<mValidateUids.size(); i++) {
17137            UidRecord uidRec = mValidateUids.valueAt(i);
17138            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
17139                continue;
17140            }
17141            uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VALIDATE_UIDS);
17142        }
17143
17144        if (mLruProcesses.size() > 0) {
17145            long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS);
17146            int total = mLruProcesses.size();
17147            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total);
17148            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
17149            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
17150            writeProcessOomListToProto(proto, ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, this,
17151                    mLruProcesses,false, dumpPackage);
17152            proto.end(lruToken);
17153        }
17154
17155        if (dumpPackage != null) {
17156            synchronized (mPidsSelfLocked) {
17157                for (int i=0; i<mPidsSelfLocked.size(); i++) {
17158                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
17159                    if (!r.pkgList.containsKey(dumpPackage)) {
17160                        continue;
17161                    }
17162                    r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PIDS_SELF_LOCKED);
17163                }
17164            }
17165        }
17166
17167        if (mImportantProcesses.size() > 0) {
17168            synchronized (mPidsSelfLocked) {
17169                for (int i=0; i<mImportantProcesses.size(); i++) {
17170                    ImportanceToken it = mImportantProcesses.valueAt(i);
17171                    ProcessRecord r = mPidsSelfLocked.get(it.pid);
17172                    if (dumpPackage != null && (r == null
17173                            || !r.pkgList.containsKey(dumpPackage))) {
17174                        continue;
17175                    }
17176                    it.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.IMPORTANT_PROCS);
17177                }
17178            }
17179        }
17180
17181        for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
17182            ProcessRecord r = mPersistentStartingProcesses.get(i);
17183            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17184                continue;
17185            }
17186            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PERSISTENT_STARTING_PROCS);
17187        }
17188
17189        for (int i=0; i<mRemovedProcesses.size(); i++) {
17190            ProcessRecord r = mRemovedProcesses.get(i);
17191            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17192                continue;
17193            }
17194            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.REMOVED_PROCS);
17195        }
17196
17197        for (int i=0; i<mProcessesOnHold.size(); i++) {
17198            ProcessRecord r = mProcessesOnHold.get(i);
17199            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17200                continue;
17201            }
17202            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ON_HOLD_PROCS);
17203        }
17204
17205        writeProcessesToGcToProto(proto, ActivityManagerServiceDumpProcessesProto.GC_PROCS, dumpPackage);
17206        mAppErrors.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.APP_ERRORS, dumpPackage);
17207
17208        if (dumpPackage == null) {
17209            mUserController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER);
17210            getGlobalConfiguration().writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION);
17211            proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
17212        }
17213
17214        if (mHomeProcess != null && (dumpPackage == null
17215                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
17216            mHomeProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HOME_PROC);
17217        }
17218
17219        if (mPreviousProcess != null && (dumpPackage == null
17220                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
17221            mPreviousProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC);
17222            proto.write(ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
17223        }
17224
17225        if (mHeavyWeightProcess != null && (dumpPackage == null
17226                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
17227            mHeavyWeightProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC);
17228        }
17229
17230        for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
17231            String pkg = entry.getKey();
17232            int mode = entry.getValue();
17233            if (dumpPackage == null || dumpPackage.equals(pkg)) {
17234                long compatToken = proto.start(ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES);
17235                proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
17236                proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE, mode);
17237                proto.end(compatToken);
17238            }
17239        }
17240
17241        final int NI = mUidObservers.getRegisteredCallbackCount();
17242        for (int i=0; i<NI; i++) {
17243            final UidObserverRegistration reg = (UidObserverRegistration)
17244                    mUidObservers.getRegisteredCallbackCookie(i);
17245            if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
17246                reg.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
17247            }
17248        }
17249
17250        for (int v : mDeviceIdleWhitelist) {
17251            proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_WHITELIST, v);
17252        }
17253
17254        for (int v : mDeviceIdleTempWhitelist) {
17255            proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
17256        }
17257
17258        if (mPendingTempWhitelist.size() > 0) {
17259            for (int i=0; i < mPendingTempWhitelist.size(); i++) {
17260                mPendingTempWhitelist.valueAt(i).writeToProto(proto,
17261                        ActivityManagerServiceDumpProcessesProto.PENDING_TEMP_WHITELIST);
17262            }
17263        }
17264
17265        if (dumpPackage == null) {
17266            final long sleepToken = proto.start(ActivityManagerServiceDumpProcessesProto.SLEEP_STATUS);
17267            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.WAKEFULNESS,
17268                    PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
17269            for (SleepToken st : mStackSupervisor.mSleepTokens) {
17270                proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
17271            }
17272            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
17273            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
17274            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
17275            proto.end(sleepToken);
17276
17277            if (mRunningVoice != null) {
17278                final long vrToken = proto.start(ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
17279                proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION, mRunningVoice.toString());
17280                mVoiceWakeLock.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
17281                proto.end(vrToken);
17282            }
17283
17284            mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
17285        }
17286
17287        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
17288                || mOrigWaitForDebugger) {
17289            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
17290                    || dumpPackage.equals(mOrigDebugApp)) {
17291                final long debugAppToken = proto.start(ActivityManagerServiceDumpProcessesProto.DEBUG);
17292                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
17293                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
17294                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
17295                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
17296                proto.end(debugAppToken);
17297            }
17298        }
17299
17300        if (mCurAppTimeTracker != null) {
17301            mCurAppTimeTracker.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER, true);
17302        }
17303
17304        if (mMemWatchProcesses.getMap().size() > 0) {
17305            final long token = proto.start(ActivityManagerServiceDumpProcessesProto.MEM_WATCH_PROCESSES);
17306            ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
17307            for (int i=0; i<procs.size(); i++) {
17308                final String proc = procs.keyAt(i);
17309                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
17310                final long ptoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.PROCS);
17311                proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.NAME, proc);
17312                for (int j=0; j<uids.size(); j++) {
17313                    final long utoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MEM_STATS);
17314                    Pair<Long, String> val = uids.valueAt(j);
17315                    proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
17316                    proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
17317                            DebugUtils.sizeValueToString(val.first, new StringBuilder()));
17318                    proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
17319                    proto.end(utoken);
17320                }
17321                proto.end(ptoken);
17322            }
17323
17324            final long dtoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.DUMP);
17325            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
17326            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
17327            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
17328            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
17329            proto.end(dtoken);
17330
17331            proto.end(token);
17332        }
17333
17334        if (mTrackAllocationApp != null) {
17335            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
17336                proto.write(ActivityManagerServiceDumpProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
17337            }
17338        }
17339
17340        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
17341                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
17342            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
17343                final long token = proto.start(ActivityManagerServiceDumpProcessesProto.PROFILE);
17344                proto.write(ActivityManagerServiceDumpProcessesProto.Profile.APP_NAME, mProfileApp);
17345                mProfileProc.writeToProto(proto,ActivityManagerServiceDumpProcessesProto.Profile.PROC);
17346                if (mProfilerInfo != null) {
17347                    mProfilerInfo.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Profile.INFO);
17348                    proto.write(ActivityManagerServiceDumpProcessesProto.Profile.TYPE, mProfileType);
17349                }
17350                proto.end(token);
17351            }
17352        }
17353
17354        if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
17355            proto.write(ActivityManagerServiceDumpProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
17356        }
17357
17358        if (dumpPackage == null) {
17359            proto.write(ActivityManagerServiceDumpProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
17360            if (mController != null) {
17361                final long token = proto.start(ActivityManagerServiceDumpProcessesProto.CONTROLLER);
17362                proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mController.toString());
17363                proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
17364                proto.end(token);
17365            }
17366            proto.write(ActivityManagerServiceDumpProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
17367            proto.write(ActivityManagerServiceDumpProcessesProto.PROCESSES_READY, mProcessesReady);
17368            proto.write(ActivityManagerServiceDumpProcessesProto.SYSTEM_READY, mSystemReady);
17369            proto.write(ActivityManagerServiceDumpProcessesProto.BOOTED, mBooted);
17370            proto.write(ActivityManagerServiceDumpProcessesProto.FACTORY_TEST, mFactoryTest);
17371            proto.write(ActivityManagerServiceDumpProcessesProto.BOOTING, mBooting);
17372            proto.write(ActivityManagerServiceDumpProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
17373            proto.write(ActivityManagerServiceDumpProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
17374            proto.write(ActivityManagerServiceDumpProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
17375            mStackSupervisor.mGoingToSleep.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP);
17376            mStackSupervisor.mLaunchingActivity.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY);
17377            proto.write(ActivityManagerServiceDumpProcessesProto.ADJ_SEQ, mAdjSeq);
17378            proto.write(ActivityManagerServiceDumpProcessesProto.LRU_SEQ, mLruSeq);
17379            proto.write(ActivityManagerServiceDumpProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
17380            proto.write(ActivityManagerServiceDumpProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
17381            proto.write(ActivityManagerServiceDumpProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
17382            proto.write(ActivityManagerServiceDumpProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
17383            proto.write(ActivityManagerServiceDumpProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
17384            proto.write(ActivityManagerServiceDumpProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
17385            long now = SystemClock.uptimeMillis();
17386            ProtoUtils.toDuration(proto, ActivityManagerServiceDumpProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
17387            proto.write(ActivityManagerServiceDumpProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
17388        }
17389
17390    }
17391
17392    void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
17393        if (mProcessesToGc.size() > 0) {
17394            long now = SystemClock.uptimeMillis();
17395            for (int i=0; i<mProcessesToGc.size(); i++) {
17396                ProcessRecord r = mProcessesToGc.get(i);
17397                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17398                    continue;
17399                }
17400                final long token = proto.start(fieldId);
17401                r.writeToProto(proto, ProcessToGcProto.PROC);
17402                proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
17403                proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
17404                proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
17405                proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory);
17406                proto.end(token);
17407            }
17408        }
17409    }
17410
17411    boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) {
17412        if (mProcessesToGc.size() > 0) {
17413            boolean printed = false;
17414            long now = SystemClock.uptimeMillis();
17415            for (int i=0; i<mProcessesToGc.size(); i++) {
17416                ProcessRecord proc = mProcessesToGc.get(i);
17417                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
17418                    continue;
17419                }
17420                if (!printed) {
17421                    if (needSep) pw.println();
17422                    needSep = true;
17423                    pw.println("  Processes that are waiting to GC:");
17424                    printed = true;
17425                }
17426                pw.print("    Process "); pw.println(proc);
17427                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
17428                        pw.print(", last gced=");
17429                        pw.print(now-proc.lastRequestedGc);
17430                        pw.print(" ms ago, last lowMem=");
17431                        pw.print(now-proc.lastLowMemory);
17432                        pw.println(" ms ago");
17433
17434            }
17435        }
17436        return needSep;
17437    }
17438
17439    void printOomLevel(PrintWriter pw, String name, int adj) {
17440        pw.print("    ");
17441        if (adj >= 0) {
17442            pw.print(' ');
17443            if (adj < 10) pw.print(' ');
17444        } else {
17445            if (adj > -10) pw.print(' ');
17446        }
17447        pw.print(adj);
17448        pw.print(": ");
17449        pw.print(name);
17450        pw.print(" (");
17451        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
17452        pw.println(")");
17453    }
17454
17455    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17456            int opti, boolean dumpAll) {
17457        boolean needSep = false;
17458
17459        if (mLruProcesses.size() > 0) {
17460            if (needSep) pw.println();
17461            needSep = true;
17462            pw.println("  OOM levels:");
17463            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
17464            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
17465            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
17466            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
17467            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
17468            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
17469            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
17470            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
17471            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
17472            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
17473            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
17474            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
17475            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
17476            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
17477
17478            if (needSep) pw.println();
17479            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
17480                    pw.print(" total, non-act at ");
17481                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
17482                    pw.print(", non-svc at ");
17483                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
17484                    pw.println("):");
17485            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
17486            needSep = true;
17487        }
17488
17489        dumpProcessesToGc(pw, needSep, null);
17490
17491        pw.println();
17492        pw.println("  mHomeProcess: " + mHomeProcess);
17493        pw.println("  mPreviousProcess: " + mPreviousProcess);
17494        if (mHeavyWeightProcess != null) {
17495            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
17496        }
17497
17498        return true;
17499    }
17500
17501    /**
17502     * There are three ways to call this:
17503     *  - no provider specified: dump all the providers
17504     *  - a flattened component name that matched an existing provider was specified as the
17505     *    first arg: dump that one provider
17506     *  - the first arg isn't the flattened component name of an existing provider:
17507     *    dump all providers whose component contains the first arg as a substring
17508     */
17509    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17510            int opti, boolean dumpAll) {
17511        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
17512    }
17513
17514    /**
17515     * Similar to the dumpProvider, but only dumps the first matching provider.
17516     * The provider is responsible for dumping as proto.
17517     */
17518    protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
17519            String[] args) {
17520        return mProviderMap.dumpProviderProto(fd, pw, name, args);
17521    }
17522
17523    static class ItemMatcher {
17524        ArrayList<ComponentName> components;
17525        ArrayList<String> strings;
17526        ArrayList<Integer> objects;
17527        boolean all;
17528
17529        ItemMatcher() {
17530            all = true;
17531        }
17532
17533        void build(String name) {
17534            ComponentName componentName = ComponentName.unflattenFromString(name);
17535            if (componentName != null) {
17536                if (components == null) {
17537                    components = new ArrayList<ComponentName>();
17538                }
17539                components.add(componentName);
17540                all = false;
17541            } else {
17542                int objectId = 0;
17543                // Not a '/' separated full component name; maybe an object ID?
17544                try {
17545                    objectId = Integer.parseInt(name, 16);
17546                    if (objects == null) {
17547                        objects = new ArrayList<Integer>();
17548                    }
17549                    objects.add(objectId);
17550                    all = false;
17551                } catch (RuntimeException e) {
17552                    // Not an integer; just do string match.
17553                    if (strings == null) {
17554                        strings = new ArrayList<String>();
17555                    }
17556                    strings.add(name);
17557                    all = false;
17558                }
17559            }
17560        }
17561
17562        int build(String[] args, int opti) {
17563            for (; opti<args.length; opti++) {
17564                String name = args[opti];
17565                if ("--".equals(name)) {
17566                    return opti+1;
17567                }
17568                build(name);
17569            }
17570            return opti;
17571        }
17572
17573        boolean match(Object object, ComponentName comp) {
17574            if (all) {
17575                return true;
17576            }
17577            if (components != null) {
17578                for (int i=0; i<components.size(); i++) {
17579                    if (components.get(i).equals(comp)) {
17580                        return true;
17581                    }
17582                }
17583            }
17584            if (objects != null) {
17585                for (int i=0; i<objects.size(); i++) {
17586                    if (System.identityHashCode(object) == objects.get(i)) {
17587                        return true;
17588                    }
17589                }
17590            }
17591            if (strings != null) {
17592                String flat = comp.flattenToString();
17593                for (int i=0; i<strings.size(); i++) {
17594                    if (flat.contains(strings.get(i))) {
17595                        return true;
17596                    }
17597                }
17598            }
17599            return false;
17600        }
17601    }
17602
17603    /**
17604     * There are three things that cmd can be:
17605     *  - a flattened component name that matches an existing activity
17606     *  - the cmd arg isn't the flattened component name of an existing activity:
17607     *    dump all activity whose component contains the cmd as a substring
17608     *  - A hex number of the ActivityRecord object instance.
17609     *
17610     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
17611     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
17612     */
17613    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17614            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
17615        ArrayList<ActivityRecord> activities;
17616
17617        synchronized (this) {
17618            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
17619                    dumpFocusedStackOnly);
17620        }
17621
17622        if (activities.size() <= 0) {
17623            return false;
17624        }
17625
17626        String[] newArgs = new String[args.length - opti];
17627        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
17628
17629        TaskRecord lastTask = null;
17630        boolean needSep = false;
17631        for (int i=activities.size()-1; i>=0; i--) {
17632            ActivityRecord r = activities.get(i);
17633            if (needSep) {
17634                pw.println();
17635            }
17636            needSep = true;
17637            synchronized (this) {
17638                final TaskRecord task = r.getTask();
17639                if (lastTask != task) {
17640                    lastTask = task;
17641                    pw.print("TASK "); pw.print(lastTask.affinity);
17642                            pw.print(" id="); pw.print(lastTask.taskId);
17643                            pw.print(" userId="); pw.println(lastTask.userId);
17644                    if (dumpAll) {
17645                        lastTask.dump(pw, "  ");
17646                    }
17647                }
17648            }
17649            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
17650        }
17651        return true;
17652    }
17653
17654    /**
17655     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
17656     * there is a thread associated with the activity.
17657     */
17658    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
17659            final ActivityRecord r, String[] args, boolean dumpAll) {
17660        String innerPrefix = prefix + "  ";
17661        synchronized (this) {
17662            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
17663                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
17664                    pw.print(" pid=");
17665                    if (r.app != null) pw.println(r.app.pid);
17666                    else pw.println("(not running)");
17667            if (dumpAll) {
17668                r.dump(pw, innerPrefix);
17669            }
17670        }
17671        if (r.app != null && r.app.thread != null) {
17672            // flush anything that is already in the PrintWriter since the thread is going
17673            // to write to the file descriptor directly
17674            pw.flush();
17675            try {
17676                TransferPipe tp = new TransferPipe();
17677                try {
17678                    r.app.thread.dumpActivity(tp.getWriteFd(),
17679                            r.appToken, innerPrefix, args);
17680                    tp.go(fd);
17681                } finally {
17682                    tp.kill();
17683                }
17684            } catch (IOException e) {
17685                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
17686            } catch (RemoteException e) {
17687                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
17688            }
17689        }
17690    }
17691
17692    void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
17693        if (mRegisteredReceivers.size() > 0) {
17694            Iterator it = mRegisteredReceivers.values().iterator();
17695            while (it.hasNext()) {
17696                ReceiverList r = (ReceiverList)it.next();
17697                r.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_LIST);
17698            }
17699        }
17700        mReceiverResolver.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_RESOLVER);
17701        for (BroadcastQueue q : mBroadcastQueues) {
17702            q.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
17703        }
17704        for (int user=0; user<mStickyBroadcasts.size(); user++) {
17705            long token = proto.start(ActivityManagerServiceDumpBroadcastsProto.STICKY_BROADCASTS);
17706            proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
17707            for (Map.Entry<String, ArrayList<Intent>> ent
17708                    : mStickyBroadcasts.valueAt(user).entrySet()) {
17709                long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
17710                proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
17711                for (Intent intent : ent.getValue()) {
17712                    intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
17713                            false, true, true, false);
17714                }
17715                proto.end(actionToken);
17716            }
17717            proto.end(token);
17718        }
17719
17720        long handlerToken = proto.start(ActivityManagerServiceDumpBroadcastsProto.HANDLER);
17721        proto.write(ActivityManagerServiceDumpBroadcastsProto.MainHandler.HANDLER, mHandler.toString());
17722        mHandler.getLooper().writeToProto(proto,
17723            ActivityManagerServiceDumpBroadcastsProto.MainHandler.LOOPER);
17724        proto.end(handlerToken);
17725    }
17726
17727    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17728            int opti, boolean dumpAll, String dumpPackage) {
17729        boolean needSep = false;
17730        boolean onlyHistory = false;
17731        boolean printedAnything = false;
17732
17733        if ("history".equals(dumpPackage)) {
17734            if (opti < args.length && "-s".equals(args[opti])) {
17735                dumpAll = false;
17736            }
17737            onlyHistory = true;
17738            dumpPackage = null;
17739        }
17740
17741        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
17742        if (!onlyHistory && dumpAll) {
17743            if (mRegisteredReceivers.size() > 0) {
17744                boolean printed = false;
17745                Iterator it = mRegisteredReceivers.values().iterator();
17746                while (it.hasNext()) {
17747                    ReceiverList r = (ReceiverList)it.next();
17748                    if (dumpPackage != null && (r.app == null ||
17749                            !dumpPackage.equals(r.app.info.packageName))) {
17750                        continue;
17751                    }
17752                    if (!printed) {
17753                        pw.println("  Registered Receivers:");
17754                        needSep = true;
17755                        printed = true;
17756                        printedAnything = true;
17757                    }
17758                    pw.print("  * "); pw.println(r);
17759                    r.dump(pw, "    ");
17760                }
17761            }
17762
17763            if (mReceiverResolver.dump(pw, needSep ?
17764                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
17765                    "    ", dumpPackage, false, false)) {
17766                needSep = true;
17767                printedAnything = true;
17768            }
17769        }
17770
17771        for (BroadcastQueue q : mBroadcastQueues) {
17772            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
17773            printedAnything |= needSep;
17774        }
17775
17776        needSep = true;
17777
17778        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
17779            for (int user=0; user<mStickyBroadcasts.size(); user++) {
17780                if (needSep) {
17781                    pw.println();
17782                }
17783                needSep = true;
17784                printedAnything = true;
17785                pw.print("  Sticky broadcasts for user ");
17786                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
17787                StringBuilder sb = new StringBuilder(128);
17788                for (Map.Entry<String, ArrayList<Intent>> ent
17789                        : mStickyBroadcasts.valueAt(user).entrySet()) {
17790                    pw.print("  * Sticky action "); pw.print(ent.getKey());
17791                    if (dumpAll) {
17792                        pw.println(":");
17793                        ArrayList<Intent> intents = ent.getValue();
17794                        final int N = intents.size();
17795                        for (int i=0; i<N; i++) {
17796                            sb.setLength(0);
17797                            sb.append("    Intent: ");
17798                            intents.get(i).toShortString(sb, false, true, false, false);
17799                            pw.println(sb.toString());
17800                            Bundle bundle = intents.get(i).getExtras();
17801                            if (bundle != null) {
17802                                pw.print("      ");
17803                                pw.println(bundle.toString());
17804                            }
17805                        }
17806                    } else {
17807                        pw.println("");
17808                    }
17809                }
17810            }
17811        }
17812
17813        if (!onlyHistory && dumpAll) {
17814            pw.println();
17815            for (BroadcastQueue queue : mBroadcastQueues) {
17816                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
17817                        + queue.mBroadcastsScheduled);
17818            }
17819            pw.println("  mHandler:");
17820            mHandler.dump(new PrintWriterPrinter(pw), "    ");
17821            needSep = true;
17822            printedAnything = true;
17823        }
17824
17825        if (!printedAnything) {
17826            pw.println("  (nothing)");
17827        }
17828    }
17829
17830    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17831            int opti, boolean dumpAll, String dumpPackage) {
17832        if (mCurBroadcastStats == null) {
17833            return;
17834        }
17835
17836        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
17837        final long now = SystemClock.elapsedRealtime();
17838        if (mLastBroadcastStats != null) {
17839            pw.print("  Last stats (from ");
17840            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
17841            pw.print(" to ");
17842            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
17843            pw.print(", ");
17844            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
17845                    - mLastBroadcastStats.mStartUptime, pw);
17846            pw.println(" uptime):");
17847            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17848                pw.println("    (nothing)");
17849            }
17850            pw.println();
17851        }
17852        pw.print("  Current stats (from ");
17853        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
17854        pw.print(" to now, ");
17855        TimeUtils.formatDuration(SystemClock.uptimeMillis()
17856                - mCurBroadcastStats.mStartUptime, pw);
17857        pw.println(" uptime):");
17858        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17859            pw.println("    (nothing)");
17860        }
17861    }
17862
17863    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17864            int opti, boolean fullCheckin, String dumpPackage) {
17865        if (mCurBroadcastStats == null) {
17866            return;
17867        }
17868
17869        if (mLastBroadcastStats != null) {
17870            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17871            if (fullCheckin) {
17872                mLastBroadcastStats = null;
17873                return;
17874            }
17875        }
17876        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17877        if (fullCheckin) {
17878            mCurBroadcastStats = null;
17879        }
17880    }
17881
17882    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17883            int opti, boolean dumpAll, String dumpPackage) {
17884        boolean needSep;
17885        boolean printedAnything = false;
17886
17887        ItemMatcher matcher = new ItemMatcher();
17888        matcher.build(args, opti);
17889
17890        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
17891
17892        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
17893        printedAnything |= needSep;
17894
17895        if (mLaunchingProviders.size() > 0) {
17896            boolean printed = false;
17897            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
17898                ContentProviderRecord r = mLaunchingProviders.get(i);
17899                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
17900                    continue;
17901                }
17902                if (!printed) {
17903                    if (needSep) pw.println();
17904                    needSep = true;
17905                    pw.println("  Launching content providers:");
17906                    printed = true;
17907                    printedAnything = true;
17908                }
17909                pw.print("  Launching #"); pw.print(i); pw.print(": ");
17910                        pw.println(r);
17911            }
17912        }
17913
17914        if (!printedAnything) {
17915            pw.println("  (nothing)");
17916        }
17917    }
17918
17919    @GuardedBy("this")
17920    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17921            int opti, boolean dumpAll, String dumpPackage) {
17922        boolean needSep = false;
17923        boolean printedAnything = false;
17924
17925        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
17926
17927        if (mGrantedUriPermissions.size() > 0) {
17928            boolean printed = false;
17929            int dumpUid = -2;
17930            if (dumpPackage != null) {
17931                try {
17932                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
17933                            MATCH_ANY_USER, 0);
17934                } catch (NameNotFoundException e) {
17935                    dumpUid = -1;
17936                }
17937            }
17938            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
17939                int uid = mGrantedUriPermissions.keyAt(i);
17940                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
17941                    continue;
17942                }
17943                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
17944                if (!printed) {
17945                    if (needSep) pw.println();
17946                    needSep = true;
17947                    pw.println("  Granted Uri Permissions:");
17948                    printed = true;
17949                    printedAnything = true;
17950                }
17951                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
17952                for (UriPermission perm : perms.values()) {
17953                    pw.print("    "); pw.println(perm);
17954                    if (dumpAll) {
17955                        perm.dump(pw, "      ");
17956                    }
17957                }
17958            }
17959        }
17960
17961        if (!printedAnything) {
17962            pw.println("  (nothing)");
17963        }
17964    }
17965
17966    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17967            int opti, boolean dumpAll, String dumpPackage) {
17968        boolean printed = false;
17969
17970        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
17971
17972        if (mIntentSenderRecords.size() > 0) {
17973            // Organize these by package name, so they are easier to read.
17974            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
17975            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
17976            final Iterator<WeakReference<PendingIntentRecord>> it
17977                    = mIntentSenderRecords.values().iterator();
17978            while (it.hasNext()) {
17979                WeakReference<PendingIntentRecord> ref = it.next();
17980                PendingIntentRecord rec = ref != null ? ref.get() : null;
17981                if (rec == null) {
17982                    weakRefs.add(ref);
17983                    continue;
17984                }
17985                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
17986                    continue;
17987                }
17988                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
17989                if (list == null) {
17990                    list = new ArrayList<>();
17991                    byPackage.put(rec.key.packageName, list);
17992                }
17993                list.add(rec);
17994            }
17995            for (int i = 0; i < byPackage.size(); i++) {
17996                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
17997                printed = true;
17998                pw.print("  * "); pw.print(byPackage.keyAt(i));
17999                pw.print(": "); pw.print(intents.size()); pw.println(" items");
18000                for (int j = 0; j < intents.size(); j++) {
18001                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
18002                    if (dumpAll) {
18003                        intents.get(j).dump(pw, "      ");
18004                    }
18005                }
18006            }
18007            if (weakRefs.size() > 0) {
18008                printed = true;
18009                pw.println("  * WEAK REFS:");
18010                for (int i = 0; i < weakRefs.size(); i++) {
18011                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
18012                }
18013            }
18014        }
18015
18016        if (!printed) {
18017            pw.println("  (nothing)");
18018        }
18019    }
18020
18021    private static final int dumpProcessList(PrintWriter pw,
18022            ActivityManagerService service, List list,
18023            String prefix, String normalLabel, String persistentLabel,
18024            String dumpPackage) {
18025        int numPers = 0;
18026        final int N = list.size()-1;
18027        for (int i=N; i>=0; i--) {
18028            ProcessRecord r = (ProcessRecord)list.get(i);
18029            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
18030                continue;
18031            }
18032            pw.println(String.format("%s%s #%2d: %s",
18033                    prefix, (r.persistent ? persistentLabel : normalLabel),
18034                    i, r.toString()));
18035            if (r.persistent) {
18036                numPers++;
18037            }
18038        }
18039        return numPers;
18040    }
18041
18042    private static final ArrayList<Pair<ProcessRecord, Integer>>
18043        sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) {
18044        ArrayList<Pair<ProcessRecord, Integer>> list
18045                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
18046        for (int i=0; i<origList.size(); i++) {
18047            ProcessRecord r = origList.get(i);
18048            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
18049                continue;
18050            }
18051            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
18052        }
18053
18054        Comparator<Pair<ProcessRecord, Integer>> comparator
18055                = new Comparator<Pair<ProcessRecord, Integer>>() {
18056            @Override
18057            public int compare(Pair<ProcessRecord, Integer> object1,
18058                    Pair<ProcessRecord, Integer> object2) {
18059                if (object1.first.setAdj != object2.first.setAdj) {
18060                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
18061                }
18062                if (object1.first.setProcState != object2.first.setProcState) {
18063                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
18064                }
18065                if (object1.second.intValue() != object2.second.intValue()) {
18066                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
18067                }
18068                return 0;
18069            }
18070        };
18071
18072        Collections.sort(list, comparator);
18073        return list;
18074    }
18075
18076    private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
18077            ActivityManagerService service, List<ProcessRecord> origList,
18078            boolean inclDetails, String dumpPackage) {
18079        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
18080        if (list.isEmpty()) return false;
18081
18082        final long curUptime = SystemClock.uptimeMillis();
18083
18084        for (int i = list.size() - 1; i >= 0; i--) {
18085            ProcessRecord r = list.get(i).first;
18086            long token = proto.start(fieldId);
18087            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
18088            proto.write(ProcessOomProto.PERSISTENT, r.persistent);
18089            proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
18090            proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
18091            int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
18092            switch (r.setSchedGroup) {
18093                case ProcessList.SCHED_GROUP_BACKGROUND:
18094                    schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
18095                    break;
18096                case ProcessList.SCHED_GROUP_DEFAULT:
18097                    schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
18098                    break;
18099                case ProcessList.SCHED_GROUP_TOP_APP:
18100                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
18101                    break;
18102                case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
18103                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
18104                    break;
18105            }
18106            if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
18107                proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
18108            }
18109            if (r.foregroundActivities) {
18110                proto.write(ProcessOomProto.ACTIVITIES, true);
18111            } else if (r.foregroundServices) {
18112                proto.write(ProcessOomProto.SERVICES, true);
18113            }
18114            proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
18115            proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
18116            r.writeToProto(proto, ProcessOomProto.PROC);
18117            proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
18118            if (r.adjSource != null || r.adjTarget != null) {
18119                if (r.adjTarget instanceof  ComponentName) {
18120                    ComponentName cn = (ComponentName) r.adjTarget;
18121                    cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
18122                } else if (r.adjTarget != null) {
18123                    proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
18124                }
18125                if (r.adjSource instanceof ProcessRecord) {
18126                    ProcessRecord p = (ProcessRecord) r.adjSource;
18127                    p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
18128                } else if (r.adjSource != null) {
18129                    proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
18130                }
18131            }
18132            if (inclDetails) {
18133                long detailToken = proto.start(ProcessOomProto.DETAIL);
18134                proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
18135                proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
18136                proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
18137                proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
18138                proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
18139                proto.write(ProcessOomProto.Detail.CURRENT_STATE,
18140                        ProcessList.makeProcStateProtoEnum(r.curProcState));
18141                proto.write(ProcessOomProto.Detail.SET_STATE,
18142                        ProcessList.makeProcStateProtoEnum(r.setProcState));
18143                proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
18144                        r.lastPss*1024, new StringBuilder()));
18145                proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
18146                        r.lastSwapPss*1024, new StringBuilder()));
18147                proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
18148                        r.lastCachedPss*1024, new StringBuilder()));
18149                proto.write(ProcessOomProto.Detail.CACHED, r.cached);
18150                proto.write(ProcessOomProto.Detail.EMPTY, r.empty);
18151                proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient);
18152
18153                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
18154                    if (r.lastCpuTime != 0) {
18155                        long uptimeSince = curUptime - service.mLastPowerCheckUptime;
18156                        long timeUsed = r.curCpuTime - r.lastCpuTime;
18157                        long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
18158                        proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
18159                        proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
18160                        proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
18161                                (100.0*timeUsed)/uptimeSince);
18162                        proto.end(cpuTimeToken);
18163                    }
18164                }
18165                proto.end(detailToken);
18166            }
18167            proto.end(token);
18168        }
18169
18170        return true;
18171    }
18172
18173    private static final boolean dumpProcessOomList(PrintWriter pw,
18174            ActivityManagerService service, List<ProcessRecord> origList,
18175            String prefix, String normalLabel, String persistentLabel,
18176            boolean inclDetails, String dumpPackage) {
18177
18178        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
18179        if (list.isEmpty()) return false;
18180
18181        final long curUptime = SystemClock.uptimeMillis();
18182        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
18183
18184        for (int i=list.size()-1; i>=0; i--) {
18185            ProcessRecord r = list.get(i).first;
18186            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
18187            char schedGroup;
18188            switch (r.setSchedGroup) {
18189                case ProcessList.SCHED_GROUP_BACKGROUND:
18190                    schedGroup = 'B';
18191                    break;
18192                case ProcessList.SCHED_GROUP_DEFAULT:
18193                    schedGroup = 'F';
18194                    break;
18195                case ProcessList.SCHED_GROUP_TOP_APP:
18196                    schedGroup = 'T';
18197                    break;
18198                default:
18199                    schedGroup = '?';
18200                    break;
18201            }
18202            char foreground;
18203            if (r.foregroundActivities) {
18204                foreground = 'A';
18205            } else if (r.foregroundServices) {
18206                foreground = 'S';
18207            } else {
18208                foreground = ' ';
18209            }
18210            String procState = ProcessList.makeProcStateString(r.curProcState);
18211            pw.print(prefix);
18212            pw.print(r.persistent ? persistentLabel : normalLabel);
18213            pw.print(" #");
18214            int num = (origList.size()-1)-list.get(i).second;
18215            if (num < 10) pw.print(' ');
18216            pw.print(num);
18217            pw.print(": ");
18218            pw.print(oomAdj);
18219            pw.print(' ');
18220            pw.print(schedGroup);
18221            pw.print('/');
18222            pw.print(foreground);
18223            pw.print('/');
18224            pw.print(procState);
18225            pw.print(" trm:");
18226            if (r.trimMemoryLevel < 10) pw.print(' ');
18227            pw.print(r.trimMemoryLevel);
18228            pw.print(' ');
18229            pw.print(r.toShortString());
18230            pw.print(" (");
18231            pw.print(r.adjType);
18232            pw.println(')');
18233            if (r.adjSource != null || r.adjTarget != null) {
18234                pw.print(prefix);
18235                pw.print("    ");
18236                if (r.adjTarget instanceof ComponentName) {
18237                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
18238                } else if (r.adjTarget != null) {
18239                    pw.print(r.adjTarget.toString());
18240                } else {
18241                    pw.print("{null}");
18242                }
18243                pw.print("<=");
18244                if (r.adjSource instanceof ProcessRecord) {
18245                    pw.print("Proc{");
18246                    pw.print(((ProcessRecord)r.adjSource).toShortString());
18247                    pw.println("}");
18248                } else if (r.adjSource != null) {
18249                    pw.println(r.adjSource.toString());
18250                } else {
18251                    pw.println("{null}");
18252                }
18253            }
18254            if (inclDetails) {
18255                pw.print(prefix);
18256                pw.print("    ");
18257                pw.print("oom: max="); pw.print(r.maxAdj);
18258                pw.print(" curRaw="); pw.print(r.curRawAdj);
18259                pw.print(" setRaw="); pw.print(r.setRawAdj);
18260                pw.print(" cur="); pw.print(r.curAdj);
18261                pw.print(" set="); pw.println(r.setAdj);
18262                pw.print(prefix);
18263                pw.print("    ");
18264                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
18265                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
18266                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
18267                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
18268                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
18269                pw.println();
18270                pw.print(prefix);
18271                pw.print("    ");
18272                pw.print("cached="); pw.print(r.cached);
18273                pw.print(" empty="); pw.print(r.empty);
18274                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
18275
18276                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
18277                    if (r.lastCpuTime != 0) {
18278                        long timeUsed = r.curCpuTime - r.lastCpuTime;
18279                        pw.print(prefix);
18280                        pw.print("    ");
18281                        pw.print("run cpu over ");
18282                        TimeUtils.formatDuration(uptimeSince, pw);
18283                        pw.print(" used ");
18284                        TimeUtils.formatDuration(timeUsed, pw);
18285                        pw.print(" (");
18286                        pw.print((timeUsed*100)/uptimeSince);
18287                        pw.println("%)");
18288                    }
18289                }
18290            }
18291        }
18292        return true;
18293    }
18294
18295    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
18296            String[] args) {
18297        ArrayList<ProcessRecord> procs;
18298        synchronized (this) {
18299            if (args != null && args.length > start
18300                    && args[start].charAt(0) != '-') {
18301                procs = new ArrayList<ProcessRecord>();
18302                int pid = -1;
18303                try {
18304                    pid = Integer.parseInt(args[start]);
18305                } catch (NumberFormatException e) {
18306                }
18307                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18308                    ProcessRecord proc = mLruProcesses.get(i);
18309                    if (proc.pid > 0 && proc.pid == pid) {
18310                        procs.add(proc);
18311                    } else if (allPkgs && proc.pkgList != null
18312                            && proc.pkgList.containsKey(args[start])) {
18313                        procs.add(proc);
18314                    } else if (proc.processName.equals(args[start])) {
18315                        procs.add(proc);
18316                    }
18317                }
18318                if (procs.size() <= 0) {
18319                    return null;
18320                }
18321            } else {
18322                procs = new ArrayList<ProcessRecord>(mLruProcesses);
18323            }
18324        }
18325        return procs;
18326    }
18327
18328    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
18329            PrintWriter pw, String[] args) {
18330        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18331        if (procs == null) {
18332            pw.println("No process found for: " + args[0]);
18333            return;
18334        }
18335
18336        long uptime = SystemClock.uptimeMillis();
18337        long realtime = SystemClock.elapsedRealtime();
18338        pw.println("Applications Graphics Acceleration Info:");
18339        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18340
18341        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18342            ProcessRecord r = procs.get(i);
18343            if (r.thread != null) {
18344                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
18345                pw.flush();
18346                try {
18347                    TransferPipe tp = new TransferPipe();
18348                    try {
18349                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
18350                        tp.go(fd);
18351                    } finally {
18352                        tp.kill();
18353                    }
18354                } catch (IOException e) {
18355                    pw.println("Failure while dumping the app: " + r);
18356                    pw.flush();
18357                } catch (RemoteException e) {
18358                    pw.println("Got a RemoteException while dumping the app " + r);
18359                    pw.flush();
18360                }
18361            }
18362        }
18363    }
18364
18365    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
18366        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18367        if (procs == null) {
18368            pw.println("No process found for: " + args[0]);
18369            return;
18370        }
18371
18372        pw.println("Applications Database Info:");
18373
18374        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18375            ProcessRecord r = procs.get(i);
18376            if (r.thread != null) {
18377                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
18378                pw.flush();
18379                try {
18380                    TransferPipe tp = new TransferPipe();
18381                    try {
18382                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
18383                        tp.go(fd);
18384                    } finally {
18385                        tp.kill();
18386                    }
18387                } catch (IOException e) {
18388                    pw.println("Failure while dumping the app: " + r);
18389                    pw.flush();
18390                } catch (RemoteException e) {
18391                    pw.println("Got a RemoteException while dumping the app " + r);
18392                    pw.flush();
18393                }
18394            }
18395        }
18396    }
18397
18398    final static class MemItem {
18399        final boolean isProc;
18400        final String label;
18401        final String shortLabel;
18402        final long pss;
18403        final long swapPss;
18404        final int id;
18405        final boolean hasActivities;
18406        ArrayList<MemItem> subitems;
18407
18408        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
18409                boolean _hasActivities) {
18410            isProc = true;
18411            label = _label;
18412            shortLabel = _shortLabel;
18413            pss = _pss;
18414            swapPss = _swapPss;
18415            id = _id;
18416            hasActivities = _hasActivities;
18417        }
18418
18419        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
18420            isProc = false;
18421            label = _label;
18422            shortLabel = _shortLabel;
18423            pss = _pss;
18424            swapPss = _swapPss;
18425            id = _id;
18426            hasActivities = false;
18427        }
18428    }
18429
18430    private static void sortMemItems(List<MemItem> items) {
18431        Collections.sort(items, new Comparator<MemItem>() {
18432            @Override
18433            public int compare(MemItem lhs, MemItem rhs) {
18434                if (lhs.pss < rhs.pss) {
18435                    return 1;
18436                } else if (lhs.pss > rhs.pss) {
18437                    return -1;
18438                }
18439                return 0;
18440            }
18441        });
18442    }
18443
18444    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
18445            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
18446        if (sort && !isCompact) {
18447            sortMemItems(items);
18448        }
18449
18450        for (int i=0; i<items.size(); i++) {
18451            MemItem mi = items.get(i);
18452            if (!isCompact) {
18453                if (dumpSwapPss) {
18454                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
18455                            mi.label, stringifyKBSize(mi.swapPss));
18456                } else {
18457                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
18458                }
18459            } else if (mi.isProc) {
18460                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
18461                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
18462                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
18463                pw.println(mi.hasActivities ? ",a" : ",e");
18464            } else {
18465                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
18466                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
18467            }
18468            if (mi.subitems != null) {
18469                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
18470                        true, isCompact, dumpSwapPss);
18471            }
18472        }
18473    }
18474
18475    static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
18476            ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
18477        if (sort) {
18478            sortMemItems(items);
18479        }
18480
18481        for (int i=0; i<items.size(); i++) {
18482            MemItem mi = items.get(i);
18483            final long token = proto.start(fieldId);
18484
18485            proto.write(MemInfoDumpProto.MemItem.TAG, tag);
18486            proto.write(MemInfoDumpProto.MemItem.LABEL, mi.shortLabel);
18487            proto.write(MemInfoDumpProto.MemItem.IS_PROC, mi.isProc);
18488            proto.write(MemInfoDumpProto.MemItem.ID, mi.id);
18489            proto.write(MemInfoDumpProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
18490            proto.write(MemInfoDumpProto.MemItem.PSS_KB, mi.pss);
18491            if (dumpSwapPss) {
18492                proto.write(MemInfoDumpProto.MemItem.SWAP_PSS_KB, mi.swapPss);
18493            }
18494            if (mi.subitems != null) {
18495                dumpMemItems(proto, MemInfoDumpProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
18496                        true, dumpSwapPss);
18497            }
18498            proto.end(token);
18499        }
18500    }
18501
18502    // These are in KB.
18503    static final long[] DUMP_MEM_BUCKETS = new long[] {
18504        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
18505        120*1024, 160*1024, 200*1024,
18506        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
18507        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
18508    };
18509
18510    static final void appendMemBucket(StringBuilder out, long memKB, String label,
18511            boolean stackLike) {
18512        int start = label.lastIndexOf('.');
18513        if (start >= 0) start++;
18514        else start = 0;
18515        int end = label.length();
18516        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
18517            if (DUMP_MEM_BUCKETS[i] >= memKB) {
18518                long bucket = DUMP_MEM_BUCKETS[i]/1024;
18519                out.append(bucket);
18520                out.append(stackLike ? "MB." : "MB ");
18521                out.append(label, start, end);
18522                return;
18523            }
18524        }
18525        out.append(memKB/1024);
18526        out.append(stackLike ? "MB." : "MB ");
18527        out.append(label, start, end);
18528    }
18529
18530    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
18531            ProcessList.NATIVE_ADJ,
18532            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
18533            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
18534            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
18535            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
18536            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
18537            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
18538    };
18539    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
18540            "Native",
18541            "System", "Persistent", "Persistent Service", "Foreground",
18542            "Visible", "Perceptible",
18543            "Heavy Weight", "Backup",
18544            "A Services", "Home",
18545            "Previous", "B Services", "Cached"
18546    };
18547    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
18548            "native",
18549            "sys", "pers", "persvc", "fore",
18550            "vis", "percept",
18551            "heavy", "backup",
18552            "servicea", "home",
18553            "prev", "serviceb", "cached"
18554    };
18555
18556    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
18557            long realtime, boolean isCheckinRequest, boolean isCompact) {
18558        if (isCompact) {
18559            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
18560        }
18561        if (isCheckinRequest || isCompact) {
18562            // short checkin version
18563            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
18564        } else {
18565            pw.println("Applications Memory Usage (in Kilobytes):");
18566            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18567        }
18568    }
18569
18570    private static final int KSM_SHARED = 0;
18571    private static final int KSM_SHARING = 1;
18572    private static final int KSM_UNSHARED = 2;
18573    private static final int KSM_VOLATILE = 3;
18574
18575    private final long[] getKsmInfo() {
18576        long[] longOut = new long[4];
18577        final int[] SINGLE_LONG_FORMAT = new int[] {
18578            PROC_SPACE_TERM| PROC_OUT_LONG
18579        };
18580        long[] longTmp = new long[1];
18581        readProcFile("/sys/kernel/mm/ksm/pages_shared",
18582                SINGLE_LONG_FORMAT, null, longTmp, null);
18583        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18584        longTmp[0] = 0;
18585        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
18586                SINGLE_LONG_FORMAT, null, longTmp, null);
18587        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18588        longTmp[0] = 0;
18589        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
18590                SINGLE_LONG_FORMAT, null, longTmp, null);
18591        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18592        longTmp[0] = 0;
18593        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
18594                SINGLE_LONG_FORMAT, null, longTmp, null);
18595        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18596        return longOut;
18597    }
18598
18599    private static String stringifySize(long size, int order) {
18600        Locale locale = Locale.US;
18601        switch (order) {
18602            case 1:
18603                return String.format(locale, "%,13d", size);
18604            case 1024:
18605                return String.format(locale, "%,9dK", size / 1024);
18606            case 1024 * 1024:
18607                return String.format(locale, "%,5dM", size / 1024 / 1024);
18608            case 1024 * 1024 * 1024:
18609                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
18610            default:
18611                throw new IllegalArgumentException("Invalid size order");
18612        }
18613    }
18614
18615    private static String stringifyKBSize(long size) {
18616        return stringifySize(size * 1024, 1024);
18617    }
18618
18619    // Update this version number if you change the 'compact' format.
18620    private static final int MEMINFO_COMPACT_VERSION = 1;
18621
18622    private static class MemoryUsageDumpOptions {
18623        boolean dumpDetails;
18624        boolean dumpFullDetails;
18625        boolean dumpDalvik;
18626        boolean dumpSummaryOnly;
18627        boolean dumpUnreachable;
18628        boolean oomOnly;
18629        boolean isCompact;
18630        boolean localOnly;
18631        boolean packages;
18632        boolean isCheckinRequest;
18633        boolean dumpSwapPss;
18634        boolean dumpProto;
18635    }
18636
18637    final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18638            String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) {
18639        MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions();
18640        opts.dumpDetails = false;
18641        opts.dumpFullDetails = false;
18642        opts.dumpDalvik = false;
18643        opts.dumpSummaryOnly = false;
18644        opts.dumpUnreachable = false;
18645        opts.oomOnly = false;
18646        opts.isCompact = false;
18647        opts.localOnly = false;
18648        opts.packages = false;
18649        opts.isCheckinRequest = false;
18650        opts.dumpSwapPss = false;
18651        opts.dumpProto = asProto;
18652
18653        int opti = 0;
18654        while (opti < args.length) {
18655            String opt = args[opti];
18656            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18657                break;
18658            }
18659            opti++;
18660            if ("-a".equals(opt)) {
18661                opts.dumpDetails = true;
18662                opts.dumpFullDetails = true;
18663                opts.dumpDalvik = true;
18664                opts.dumpSwapPss = true;
18665            } else if ("-d".equals(opt)) {
18666                opts.dumpDalvik = true;
18667            } else if ("-c".equals(opt)) {
18668                opts.isCompact = true;
18669            } else if ("-s".equals(opt)) {
18670                opts.dumpDetails = true;
18671                opts.dumpSummaryOnly = true;
18672            } else if ("-S".equals(opt)) {
18673                opts.dumpSwapPss = true;
18674            } else if ("--unreachable".equals(opt)) {
18675                opts.dumpUnreachable = true;
18676            } else if ("--oom".equals(opt)) {
18677                opts.oomOnly = true;
18678            } else if ("--local".equals(opt)) {
18679                opts.localOnly = true;
18680            } else if ("--package".equals(opt)) {
18681                opts.packages = true;
18682            } else if ("--checkin".equals(opt)) {
18683                opts.isCheckinRequest = true;
18684            } else if ("--proto".equals(opt)) {
18685                opts.dumpProto = true;
18686
18687            } else if ("-h".equals(opt)) {
18688                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
18689                pw.println("  -a: include all available information for each process.");
18690                pw.println("  -d: include dalvik details.");
18691                pw.println("  -c: dump in a compact machine-parseable representation.");
18692                pw.println("  -s: dump only summary of application memory usage.");
18693                pw.println("  -S: dump also SwapPss.");
18694                pw.println("  --oom: only show processes organized by oom adj.");
18695                pw.println("  --local: only collect details locally, don't call process.");
18696                pw.println("  --package: interpret process arg as package, dumping all");
18697                pw.println("             processes that have loaded that package.");
18698                pw.println("  --checkin: dump data for a checkin");
18699                pw.println("  --proto: dump data to proto");
18700                pw.println("If [process] is specified it can be the name or ");
18701                pw.println("pid of a specific process to dump.");
18702                return;
18703            } else {
18704                pw.println("Unknown argument: " + opt + "; use -h for help");
18705            }
18706        }
18707
18708        String[] innerArgs = new String[args.length-opti];
18709        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
18710
18711        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
18712        if (opts.dumpProto) {
18713            dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
18714        } else {
18715            dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
18716        }
18717    }
18718
18719    private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18720            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18721            ArrayList<ProcessRecord> procs, PrintWriter categoryPw) {
18722        long uptime = SystemClock.uptimeMillis();
18723        long realtime = SystemClock.elapsedRealtime();
18724        final long[] tmpLong = new long[1];
18725
18726        if (procs == null) {
18727            // No Java processes.  Maybe they want to print a native process.
18728            String proc = "N/A";
18729            if (innerArgs.length > 0) {
18730                proc = innerArgs[0];
18731                if (proc.charAt(0) != '-') {
18732                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
18733                            = new ArrayList<ProcessCpuTracker.Stats>();
18734                    updateCpuStatsNow();
18735                    int findPid = -1;
18736                    try {
18737                        findPid = Integer.parseInt(innerArgs[0]);
18738                    } catch (NumberFormatException e) {
18739                    }
18740                    synchronized (mProcessCpuTracker) {
18741                        final int N = mProcessCpuTracker.countStats();
18742                        for (int i=0; i<N; i++) {
18743                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18744                            if (st.pid == findPid || (st.baseName != null
18745                                    && st.baseName.equals(innerArgs[0]))) {
18746                                nativeProcs.add(st);
18747                            }
18748                        }
18749                    }
18750                    if (nativeProcs.size() > 0) {
18751                        dumpApplicationMemoryUsageHeader(pw, uptime, realtime,
18752                                opts.isCheckinRequest, opts.isCompact);
18753                        Debug.MemoryInfo mi = null;
18754                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18755                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18756                            final int pid = r.pid;
18757                            if (!opts.isCheckinRequest && opts.dumpDetails) {
18758                                pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
18759                            }
18760                            if (mi == null) {
18761                                mi = new Debug.MemoryInfo();
18762                            }
18763                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18764                                Debug.getMemoryInfo(pid, mi);
18765                            } else {
18766                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18767                                mi.dalvikPrivateDirty = (int)tmpLong[0];
18768                            }
18769                            ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest,
18770                                    opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18771                                    pid, r.baseName, 0, 0, 0, 0, 0, 0);
18772                            if (opts.isCheckinRequest) {
18773                                pw.println();
18774                            }
18775                        }
18776                        return;
18777                    }
18778                }
18779            }
18780            pw.println("No process found for: " + proc);
18781            return;
18782        }
18783
18784        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18785            opts.dumpDetails = true;
18786        }
18787
18788        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
18789
18790        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18791        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18792        long nativePss = 0;
18793        long nativeSwapPss = 0;
18794        long dalvikPss = 0;
18795        long dalvikSwapPss = 0;
18796        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18797                EmptyArray.LONG;
18798        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18799                EmptyArray.LONG;
18800        long otherPss = 0;
18801        long otherSwapPss = 0;
18802        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18803        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18804
18805        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18806        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18807        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18808                new ArrayList[DUMP_MEM_OOM_LABEL.length];
18809
18810        long totalPss = 0;
18811        long totalSwapPss = 0;
18812        long cachedPss = 0;
18813        long cachedSwapPss = 0;
18814        boolean hasSwapPss = false;
18815
18816        Debug.MemoryInfo mi = null;
18817        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18818            final ProcessRecord r = procs.get(i);
18819            final IApplicationThread thread;
18820            final int pid;
18821            final int oomAdj;
18822            final boolean hasActivities;
18823            synchronized (this) {
18824                thread = r.thread;
18825                pid = r.pid;
18826                oomAdj = r.getSetAdjWithServices();
18827                hasActivities = r.activities.size() > 0;
18828            }
18829            if (thread != null) {
18830                if (!opts.isCheckinRequest && opts.dumpDetails) {
18831                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
18832                }
18833                if (mi == null) {
18834                    mi = new Debug.MemoryInfo();
18835                }
18836                final int reportType;
18837                final long startTime;
18838                final long endTime;
18839                if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18840                    reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
18841                    startTime = SystemClock.currentThreadTimeMillis();
18842                    Debug.getMemoryInfo(pid, mi);
18843                    endTime = SystemClock.currentThreadTimeMillis();
18844                    hasSwapPss = mi.hasSwappedOutPss;
18845                } else {
18846                    reportType = ProcessStats.ADD_PSS_EXTERNAL;
18847                    startTime = SystemClock.currentThreadTimeMillis();
18848                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18849                    endTime = SystemClock.currentThreadTimeMillis();
18850                    mi.dalvikPrivateDirty = (int)tmpLong[0];
18851                }
18852                if (opts.dumpDetails) {
18853                    if (opts.localOnly) {
18854                        ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
18855                                opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
18856                        if (opts.isCheckinRequest) {
18857                            pw.println();
18858                        }
18859                    } else {
18860                        pw.flush();
18861                        try {
18862                            TransferPipe tp = new TransferPipe();
18863                            try {
18864                                thread.dumpMemInfo(tp.getWriteFd(),
18865                                        mi, opts.isCheckinRequest, opts.dumpFullDetails,
18866                                        opts.dumpDalvik, opts.dumpSummaryOnly, opts.dumpUnreachable, innerArgs);
18867                                tp.go(fd);
18868                            } finally {
18869                                tp.kill();
18870                            }
18871                        } catch (IOException e) {
18872                            if (!opts.isCheckinRequest) {
18873                                pw.println("Got IoException! " + e);
18874                                pw.flush();
18875                            }
18876                        } catch (RemoteException e) {
18877                            if (!opts.isCheckinRequest) {
18878                                pw.println("Got RemoteException! " + e);
18879                                pw.flush();
18880                            }
18881                        }
18882                    }
18883                }
18884
18885                final long myTotalPss = mi.getTotalPss();
18886                final long myTotalUss = mi.getTotalUss();
18887                final long myTotalRss = mi.getTotalRss();
18888                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18889
18890                synchronized (this) {
18891                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
18892                        // Record this for posterity if the process has been stable.
18893                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
18894                                reportType, endTime-startTime, r.pkgList);
18895                    }
18896                }
18897
18898                if (!opts.isCheckinRequest && mi != null) {
18899                    totalPss += myTotalPss;
18900                    totalSwapPss += myTotalSwapPss;
18901                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
18902                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
18903                            myTotalSwapPss, pid, hasActivities);
18904                    procMems.add(pssItem);
18905                    procMemsMap.put(pid, pssItem);
18906
18907                    nativePss += mi.nativePss;
18908                    nativeSwapPss += mi.nativeSwappedOutPss;
18909                    dalvikPss += mi.dalvikPss;
18910                    dalvikSwapPss += mi.dalvikSwappedOutPss;
18911                    for (int j=0; j<dalvikSubitemPss.length; j++) {
18912                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18913                        dalvikSubitemSwapPss[j] +=
18914                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18915                    }
18916                    otherPss += mi.otherPss;
18917                    otherSwapPss += mi.otherSwappedOutPss;
18918                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18919                        long mem = mi.getOtherPss(j);
18920                        miscPss[j] += mem;
18921                        otherPss -= mem;
18922                        mem = mi.getOtherSwappedOutPss(j);
18923                        miscSwapPss[j] += mem;
18924                        otherSwapPss -= mem;
18925                    }
18926
18927                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
18928                        cachedPss += myTotalPss;
18929                        cachedSwapPss += myTotalSwapPss;
18930                    }
18931
18932                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
18933                        if (oomIndex == (oomPss.length - 1)
18934                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
18935                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
18936                            oomPss[oomIndex] += myTotalPss;
18937                            oomSwapPss[oomIndex] += myTotalSwapPss;
18938                            if (oomProcs[oomIndex] == null) {
18939                                oomProcs[oomIndex] = new ArrayList<MemItem>();
18940                            }
18941                            oomProcs[oomIndex].add(pssItem);
18942                            break;
18943                        }
18944                    }
18945                }
18946            }
18947        }
18948
18949        long nativeProcTotalPss = 0;
18950
18951        if (!opts.isCheckinRequest && procs.size() > 1 && !opts.packages) {
18952            // If we are showing aggregations, also look for native processes to
18953            // include so that our aggregations are more accurate.
18954            updateCpuStatsNow();
18955            mi = null;
18956            synchronized (mProcessCpuTracker) {
18957                final int N = mProcessCpuTracker.countStats();
18958                for (int i=0; i<N; i++) {
18959                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18960                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
18961                        if (mi == null) {
18962                            mi = new Debug.MemoryInfo();
18963                        }
18964                        if (!brief && !opts.oomOnly) {
18965                            Debug.getMemoryInfo(st.pid, mi);
18966                        } else {
18967                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
18968                            mi.nativePrivateDirty = (int)tmpLong[0];
18969                        }
18970
18971                        final long myTotalPss = mi.getTotalPss();
18972                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18973                        totalPss += myTotalPss;
18974                        totalSwapPss += myTotalSwapPss;
18975                        nativeProcTotalPss += myTotalPss;
18976
18977                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
18978                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
18979                        procMems.add(pssItem);
18980
18981                        nativePss += mi.nativePss;
18982                        nativeSwapPss += mi.nativeSwappedOutPss;
18983                        dalvikPss += mi.dalvikPss;
18984                        dalvikSwapPss += mi.dalvikSwappedOutPss;
18985                        for (int j=0; j<dalvikSubitemPss.length; j++) {
18986                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18987                            dalvikSubitemSwapPss[j] +=
18988                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18989                        }
18990                        otherPss += mi.otherPss;
18991                        otherSwapPss += mi.otherSwappedOutPss;
18992                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18993                            long mem = mi.getOtherPss(j);
18994                            miscPss[j] += mem;
18995                            otherPss -= mem;
18996                            mem = mi.getOtherSwappedOutPss(j);
18997                            miscSwapPss[j] += mem;
18998                            otherSwapPss -= mem;
18999                        }
19000                        oomPss[0] += myTotalPss;
19001                        oomSwapPss[0] += myTotalSwapPss;
19002                        if (oomProcs[0] == null) {
19003                            oomProcs[0] = new ArrayList<MemItem>();
19004                        }
19005                        oomProcs[0].add(pssItem);
19006                    }
19007                }
19008            }
19009
19010            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19011
19012            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19013            final int dalvikId = -2;
19014            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19015            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19016            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19017                String label = Debug.MemoryInfo.getOtherLabel(j);
19018                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19019            }
19020            if (dalvikSubitemPss.length > 0) {
19021                // Add dalvik subitems.
19022                for (MemItem memItem : catMems) {
19023                    int memItemStart = 0, memItemEnd = 0;
19024                    if (memItem.id == dalvikId) {
19025                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19026                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19027                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19028                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19029                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19030                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19031                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19032                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19033                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19034                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19035                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19036                    } else {
19037                        continue;  // No subitems, continue.
19038                    }
19039                    memItem.subitems = new ArrayList<MemItem>();
19040                    for (int j=memItemStart; j<=memItemEnd; j++) {
19041                        final String name = Debug.MemoryInfo.getOtherLabel(
19042                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
19043                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19044                                dalvikSubitemSwapPss[j], j));
19045                    }
19046                }
19047            }
19048
19049            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19050            for (int j=0; j<oomPss.length; j++) {
19051                if (oomPss[j] != 0) {
19052                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19053                            : DUMP_MEM_OOM_LABEL[j];
19054                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19055                            DUMP_MEM_OOM_ADJ[j]);
19056                    item.subitems = oomProcs[j];
19057                    oomMems.add(item);
19058                }
19059            }
19060
19061            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19062            if (!brief && !opts.oomOnly && !opts.isCompact) {
19063                pw.println();
19064                pw.println("Total PSS by process:");
19065                dumpMemItems(pw, "  ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
19066                pw.println();
19067            }
19068            if (!opts.isCompact) {
19069                pw.println("Total PSS by OOM adjustment:");
19070            }
19071            dumpMemItems(pw, "  ", "oom", oomMems, false, opts.isCompact, opts.dumpSwapPss);
19072            if (!brief && !opts.oomOnly) {
19073                PrintWriter out = categoryPw != null ? categoryPw : pw;
19074                if (!opts.isCompact) {
19075                    out.println();
19076                    out.println("Total PSS by category:");
19077                }
19078                dumpMemItems(out, "  ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
19079            }
19080            if (!opts.isCompact) {
19081                pw.println();
19082            }
19083            MemInfoReader memInfo = new MemInfoReader();
19084            memInfo.readMemInfo();
19085            if (nativeProcTotalPss > 0) {
19086                synchronized (this) {
19087                    final long cachedKb = memInfo.getCachedSizeKb();
19088                    final long freeKb = memInfo.getFreeSizeKb();
19089                    final long zramKb = memInfo.getZramTotalSizeKb();
19090                    final long kernelKb = memInfo.getKernelUsedSizeKb();
19091                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19092                            kernelKb*1024, nativeProcTotalPss*1024);
19093                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19094                            nativeProcTotalPss);
19095                }
19096            }
19097            if (!brief) {
19098                if (!opts.isCompact) {
19099                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
19100                    pw.print(" (status ");
19101                    switch (mLastMemoryLevel) {
19102                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
19103                            pw.println("normal)");
19104                            break;
19105                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
19106                            pw.println("moderate)");
19107                            break;
19108                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
19109                            pw.println("low)");
19110                            break;
19111                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19112                            pw.println("critical)");
19113                            break;
19114                        default:
19115                            pw.print(mLastMemoryLevel);
19116                            pw.println(")");
19117                            break;
19118                    }
19119                    pw.print(" Free RAM: ");
19120                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19121                            + memInfo.getFreeSizeKb()));
19122                    pw.print(" (");
19123                    pw.print(stringifyKBSize(cachedPss));
19124                    pw.print(" cached pss + ");
19125                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
19126                    pw.print(" cached kernel + ");
19127                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
19128                    pw.println(" free)");
19129                } else {
19130                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
19131                    pw.print(cachedPss + memInfo.getCachedSizeKb()
19132                            + memInfo.getFreeSizeKb()); pw.print(",");
19133                    pw.println(totalPss - cachedPss);
19134                }
19135            }
19136            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19137                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19138                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19139            if (!opts.isCompact) {
19140                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
19141                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
19142                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
19143                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
19144                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
19145            } else {
19146                pw.print("lostram,"); pw.println(lostRAM);
19147            }
19148            if (!brief) {
19149                if (memInfo.getZramTotalSizeKb() != 0) {
19150                    if (!opts.isCompact) {
19151                        pw.print("     ZRAM: ");
19152                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
19153                                pw.print(" physical used for ");
19154                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
19155                                        - memInfo.getSwapFreeSizeKb()));
19156                                pw.print(" in swap (");
19157                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
19158                                pw.println(" total swap)");
19159                    } else {
19160                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
19161                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
19162                                pw.println(memInfo.getSwapFreeSizeKb());
19163                    }
19164                }
19165                final long[] ksm = getKsmInfo();
19166                if (!opts.isCompact) {
19167                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
19168                            || ksm[KSM_VOLATILE] != 0) {
19169                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
19170                                pw.print(" saved from shared ");
19171                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
19172                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
19173                                pw.print(" unshared; ");
19174                                pw.print(stringifyKBSize(
19175                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
19176                    }
19177                    pw.print("   Tuning: ");
19178                    pw.print(ActivityManager.staticGetMemoryClass());
19179                    pw.print(" (large ");
19180                    pw.print(ActivityManager.staticGetLargeMemoryClass());
19181                    pw.print("), oom ");
19182                    pw.print(stringifySize(
19183                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
19184                    pw.print(", restore limit ");
19185                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
19186                    if (ActivityManager.isLowRamDeviceStatic()) {
19187                        pw.print(" (low-ram)");
19188                    }
19189                    if (ActivityManager.isHighEndGfx()) {
19190                        pw.print(" (high-end-gfx)");
19191                    }
19192                    pw.println();
19193                } else {
19194                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
19195                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
19196                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
19197                    pw.print("tuning,");
19198                    pw.print(ActivityManager.staticGetMemoryClass());
19199                    pw.print(',');
19200                    pw.print(ActivityManager.staticGetLargeMemoryClass());
19201                    pw.print(',');
19202                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
19203                    if (ActivityManager.isLowRamDeviceStatic()) {
19204                        pw.print(",low-ram");
19205                    }
19206                    if (ActivityManager.isHighEndGfx()) {
19207                        pw.print(",high-end-gfx");
19208                    }
19209                    pw.println();
19210                }
19211            }
19212        }
19213    }
19214
19215    private final void dumpApplicationMemoryUsage(FileDescriptor fd,
19216            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
19217            ArrayList<ProcessRecord> procs) {
19218        final long uptimeMs = SystemClock.uptimeMillis();
19219        final long realtimeMs = SystemClock.elapsedRealtime();
19220        final long[] tmpLong = new long[1];
19221
19222        if (procs == null) {
19223            // No Java processes.  Maybe they want to print a native process.
19224            String proc = "N/A";
19225            if (innerArgs.length > 0) {
19226                proc = innerArgs[0];
19227                if (proc.charAt(0) != '-') {
19228                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
19229                            = new ArrayList<ProcessCpuTracker.Stats>();
19230                    updateCpuStatsNow();
19231                    int findPid = -1;
19232                    try {
19233                        findPid = Integer.parseInt(innerArgs[0]);
19234                    } catch (NumberFormatException e) {
19235                    }
19236                    synchronized (mProcessCpuTracker) {
19237                        final int N = mProcessCpuTracker.countStats();
19238                        for (int i=0; i<N; i++) {
19239                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19240                            if (st.pid == findPid || (st.baseName != null
19241                                    && st.baseName.equals(innerArgs[0]))) {
19242                                nativeProcs.add(st);
19243                            }
19244                        }
19245                    }
19246                    if (nativeProcs.size() > 0) {
19247                        ProtoOutputStream proto = new ProtoOutputStream(fd);
19248
19249                        proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
19250                        proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
19251                        Debug.MemoryInfo mi = null;
19252                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
19253                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
19254                            final int pid = r.pid;
19255                            final long nToken = proto.start(MemInfoDumpProto.NATIVE_PROCESSES);
19256
19257                            proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
19258                            proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName);
19259
19260                            if (mi == null) {
19261                                mi = new Debug.MemoryInfo();
19262                            }
19263                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19264                                Debug.getMemoryInfo(pid, mi);
19265                            } else {
19266                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
19267                                mi.dalvikPrivateDirty = (int)tmpLong[0];
19268                            }
19269                            ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19270                                    opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19271
19272                            proto.end(nToken);
19273                        }
19274
19275                        proto.flush();
19276                        return;
19277                    }
19278                }
19279            }
19280            Log.d(TAG, "No process found for: " + innerArgs[0]);
19281            return;
19282        }
19283
19284        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
19285            opts.dumpDetails = true;
19286        }
19287
19288        ProtoOutputStream proto = new ProtoOutputStream(fd);
19289
19290        proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
19291        proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
19292
19293        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
19294        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
19295        long nativePss = 0;
19296        long nativeSwapPss = 0;
19297        long dalvikPss = 0;
19298        long dalvikSwapPss = 0;
19299        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19300                EmptyArray.LONG;
19301        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19302                EmptyArray.LONG;
19303        long otherPss = 0;
19304        long otherSwapPss = 0;
19305        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19306        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19307
19308        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19309        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19310        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
19311                new ArrayList[DUMP_MEM_OOM_LABEL.length];
19312
19313        long totalPss = 0;
19314        long totalSwapPss = 0;
19315        long cachedPss = 0;
19316        long cachedSwapPss = 0;
19317        boolean hasSwapPss = false;
19318
19319        Debug.MemoryInfo mi = null;
19320        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
19321            final ProcessRecord r = procs.get(i);
19322            final IApplicationThread thread;
19323            final int pid;
19324            final int oomAdj;
19325            final boolean hasActivities;
19326            synchronized (this) {
19327                thread = r.thread;
19328                pid = r.pid;
19329                oomAdj = r.getSetAdjWithServices();
19330                hasActivities = r.activities.size() > 0;
19331            }
19332            if (thread == null) {
19333                continue;
19334            }
19335            if (mi == null) {
19336                mi = new Debug.MemoryInfo();
19337            }
19338            final int reportType;
19339            final long startTime;
19340            final long endTime;
19341            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19342                reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
19343                startTime = SystemClock.currentThreadTimeMillis();
19344                Debug.getMemoryInfo(pid, mi);
19345                endTime = SystemClock.currentThreadTimeMillis();
19346                hasSwapPss = mi.hasSwappedOutPss;
19347            } else {
19348                reportType = ProcessStats.ADD_PSS_EXTERNAL;
19349                startTime = SystemClock.currentThreadTimeMillis();
19350                mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
19351                endTime = SystemClock.currentThreadTimeMillis();
19352                mi.dalvikPrivateDirty = (int) tmpLong[0];
19353            }
19354            if (opts.dumpDetails) {
19355                if (opts.localOnly) {
19356                    final long aToken = proto.start(MemInfoDumpProto.APP_PROCESSES);
19357                    final long mToken = proto.start(MemInfoDumpProto.AppData.PROCESS_MEMORY);
19358                    proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
19359                    proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.processName);
19360                    ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19361                            opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19362                    proto.end(mToken);
19363                    proto.end(aToken);
19364                } else {
19365                    try {
19366                        ByteTransferPipe tp = new ByteTransferPipe();
19367                        try {
19368                            thread.dumpMemInfoProto(tp.getWriteFd(),
19369                                mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
19370                                opts.dumpUnreachable, innerArgs);
19371                            proto.write(MemInfoDumpProto.APP_PROCESSES, tp.get());
19372                        } finally {
19373                            tp.kill();
19374                        }
19375                    } catch (IOException e) {
19376                        Log.e(TAG, "Got IOException!", e);
19377                    } catch (RemoteException e) {
19378                        Log.e(TAG, "Got RemoteException!", e);
19379                    }
19380                }
19381            }
19382
19383            final long myTotalPss = mi.getTotalPss();
19384            final long myTotalUss = mi.getTotalUss();
19385            final long myTotalRss = mi.getTotalRss();
19386            final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19387
19388            synchronized (this) {
19389                if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
19390                    // Record this for posterity if the process has been stable.
19391                    r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
19392                            reportType, endTime-startTime, r.pkgList);
19393                }
19394            }
19395
19396            if (!opts.isCheckinRequest && mi != null) {
19397                totalPss += myTotalPss;
19398                totalSwapPss += myTotalSwapPss;
19399                MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
19400                        (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
19401                        myTotalSwapPss, pid, hasActivities);
19402                procMems.add(pssItem);
19403                procMemsMap.put(pid, pssItem);
19404
19405                nativePss += mi.nativePss;
19406                nativeSwapPss += mi.nativeSwappedOutPss;
19407                dalvikPss += mi.dalvikPss;
19408                dalvikSwapPss += mi.dalvikSwappedOutPss;
19409                for (int j=0; j<dalvikSubitemPss.length; j++) {
19410                    dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19411                    dalvikSubitemSwapPss[j] +=
19412                            mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19413                }
19414                otherPss += mi.otherPss;
19415                otherSwapPss += mi.otherSwappedOutPss;
19416                for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19417                    long mem = mi.getOtherPss(j);
19418                    miscPss[j] += mem;
19419                    otherPss -= mem;
19420                    mem = mi.getOtherSwappedOutPss(j);
19421                    miscSwapPss[j] += mem;
19422                    otherSwapPss -= mem;
19423                }
19424
19425                if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19426                    cachedPss += myTotalPss;
19427                    cachedSwapPss += myTotalSwapPss;
19428                }
19429
19430                for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
19431                    if (oomIndex == (oomPss.length - 1)
19432                            || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
19433                                    && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
19434                        oomPss[oomIndex] += myTotalPss;
19435                        oomSwapPss[oomIndex] += myTotalSwapPss;
19436                        if (oomProcs[oomIndex] == null) {
19437                            oomProcs[oomIndex] = new ArrayList<MemItem>();
19438                        }
19439                        oomProcs[oomIndex].add(pssItem);
19440                        break;
19441                    }
19442                }
19443            }
19444        }
19445
19446        long nativeProcTotalPss = 0;
19447
19448        if (procs.size() > 1 && !opts.packages) {
19449            // If we are showing aggregations, also look for native processes to
19450            // include so that our aggregations are more accurate.
19451            updateCpuStatsNow();
19452            mi = null;
19453            synchronized (mProcessCpuTracker) {
19454                final int N = mProcessCpuTracker.countStats();
19455                for (int i=0; i<N; i++) {
19456                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19457                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
19458                        if (mi == null) {
19459                            mi = new Debug.MemoryInfo();
19460                        }
19461                        if (!brief && !opts.oomOnly) {
19462                            Debug.getMemoryInfo(st.pid, mi);
19463                        } else {
19464                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19465                            mi.nativePrivateDirty = (int)tmpLong[0];
19466                        }
19467
19468                        final long myTotalPss = mi.getTotalPss();
19469                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19470                        totalPss += myTotalPss;
19471                        nativeProcTotalPss += myTotalPss;
19472
19473                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19474                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19475                        procMems.add(pssItem);
19476
19477                        nativePss += mi.nativePss;
19478                        nativeSwapPss += mi.nativeSwappedOutPss;
19479                        dalvikPss += mi.dalvikPss;
19480                        dalvikSwapPss += mi.dalvikSwappedOutPss;
19481                        for (int j=0; j<dalvikSubitemPss.length; j++) {
19482                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19483                            dalvikSubitemSwapPss[j] +=
19484                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19485                        }
19486                        otherPss += mi.otherPss;
19487                        otherSwapPss += mi.otherSwappedOutPss;
19488                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19489                            long mem = mi.getOtherPss(j);
19490                            miscPss[j] += mem;
19491                            otherPss -= mem;
19492                            mem = mi.getOtherSwappedOutPss(j);
19493                            miscSwapPss[j] += mem;
19494                            otherSwapPss -= mem;
19495                        }
19496                        oomPss[0] += myTotalPss;
19497                        oomSwapPss[0] += myTotalSwapPss;
19498                        if (oomProcs[0] == null) {
19499                            oomProcs[0] = new ArrayList<MemItem>();
19500                        }
19501                        oomProcs[0].add(pssItem);
19502                    }
19503                }
19504            }
19505
19506            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19507
19508            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19509            final int dalvikId = -2;
19510            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19511            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19512            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19513                String label = Debug.MemoryInfo.getOtherLabel(j);
19514                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19515            }
19516            if (dalvikSubitemPss.length > 0) {
19517                // Add dalvik subitems.
19518                for (MemItem memItem : catMems) {
19519                    int memItemStart = 0, memItemEnd = 0;
19520                    if (memItem.id == dalvikId) {
19521                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19522                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19523                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19524                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19525                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19526                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19527                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19528                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19529                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19530                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19531                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19532                    } else {
19533                        continue;  // No subitems, continue.
19534                    }
19535                    memItem.subitems = new ArrayList<MemItem>();
19536                    for (int j=memItemStart; j<=memItemEnd; j++) {
19537                        final String name = Debug.MemoryInfo.getOtherLabel(
19538                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
19539                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19540                                dalvikSubitemSwapPss[j], j));
19541                    }
19542                }
19543            }
19544
19545            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19546            for (int j=0; j<oomPss.length; j++) {
19547                if (oomPss[j] != 0) {
19548                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19549                            : DUMP_MEM_OOM_LABEL[j];
19550                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19551                            DUMP_MEM_OOM_ADJ[j]);
19552                    item.subitems = oomProcs[j];
19553                    oomMems.add(item);
19554                }
19555            }
19556
19557            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19558            if (!opts.oomOnly) {
19559                dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_PROCESS, "proc",
19560                        procMems, true, opts.dumpSwapPss);
19561            }
19562            dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
19563                    oomMems, false, opts.dumpSwapPss);
19564            if (!brief && !opts.oomOnly) {
19565                dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_CATEGORY, "cat",
19566                        catMems, true, opts.dumpSwapPss);
19567            }
19568            MemInfoReader memInfo = new MemInfoReader();
19569            memInfo.readMemInfo();
19570            if (nativeProcTotalPss > 0) {
19571                synchronized (this) {
19572                    final long cachedKb = memInfo.getCachedSizeKb();
19573                    final long freeKb = memInfo.getFreeSizeKb();
19574                    final long zramKb = memInfo.getZramTotalSizeKb();
19575                    final long kernelKb = memInfo.getKernelUsedSizeKb();
19576                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19577                            kernelKb*1024, nativeProcTotalPss*1024);
19578                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19579                            nativeProcTotalPss);
19580                }
19581            }
19582            if (!brief) {
19583                proto.write(MemInfoDumpProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
19584                proto.write(MemInfoDumpProto.STATUS, mLastMemoryLevel);
19585                proto.write(MemInfoDumpProto.CACHED_PSS_KB, cachedPss);
19586                proto.write(MemInfoDumpProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
19587                proto.write(MemInfoDumpProto.FREE_KB, memInfo.getFreeSizeKb());
19588            }
19589            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19590                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19591                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19592            proto.write(MemInfoDumpProto.USED_PSS_KB, totalPss - cachedPss);
19593            proto.write(MemInfoDumpProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
19594            proto.write(MemInfoDumpProto.LOST_RAM_KB, lostRAM);
19595            if (!brief) {
19596                if (memInfo.getZramTotalSizeKb() != 0) {
19597                    proto.write(MemInfoDumpProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
19598                    proto.write(MemInfoDumpProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
19599                            memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
19600                    proto.write(MemInfoDumpProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
19601                }
19602                final long[] ksm = getKsmInfo();
19603                proto.write(MemInfoDumpProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
19604                proto.write(MemInfoDumpProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
19605                proto.write(MemInfoDumpProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
19606                proto.write(MemInfoDumpProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
19607
19608                proto.write(MemInfoDumpProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
19609                proto.write(MemInfoDumpProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
19610                proto.write(MemInfoDumpProto.OOM_KB,
19611                        mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
19612                proto.write(MemInfoDumpProto.RESTORE_LIMIT_KB,
19613                        mProcessList.getCachedRestoreThresholdKb());
19614
19615                proto.write(MemInfoDumpProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
19616                proto.write(MemInfoDumpProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
19617            }
19618        }
19619
19620        proto.flush();
19621    }
19622
19623    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
19624            long memtrack, String name) {
19625        sb.append("  ");
19626        sb.append(ProcessList.makeOomAdjString(oomAdj));
19627        sb.append(' ');
19628        sb.append(ProcessList.makeProcStateString(procState));
19629        sb.append(' ');
19630        ProcessList.appendRamKb(sb, pss);
19631        sb.append(": ");
19632        sb.append(name);
19633        if (memtrack > 0) {
19634            sb.append(" (");
19635            sb.append(stringifyKBSize(memtrack));
19636            sb.append(" memtrack)");
19637        }
19638    }
19639
19640    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
19641        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
19642        sb.append(" (pid ");
19643        sb.append(mi.pid);
19644        sb.append(") ");
19645        sb.append(mi.adjType);
19646        sb.append('\n');
19647        if (mi.adjReason != null) {
19648            sb.append("                      ");
19649            sb.append(mi.adjReason);
19650            sb.append('\n');
19651        }
19652    }
19653
19654    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
19655        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
19656        for (int i=0, N=memInfos.size(); i<N; i++) {
19657            ProcessMemInfo mi = memInfos.get(i);
19658            infoMap.put(mi.pid, mi);
19659        }
19660        updateCpuStatsNow();
19661        long[] memtrackTmp = new long[1];
19662        final List<ProcessCpuTracker.Stats> stats;
19663        // Get a list of Stats that have vsize > 0
19664        synchronized (mProcessCpuTracker) {
19665            stats = mProcessCpuTracker.getStats((st) -> {
19666                return st.vsize > 0;
19667            });
19668        }
19669        final int statsCount = stats.size();
19670        for (int i = 0; i < statsCount; i++) {
19671            ProcessCpuTracker.Stats st = stats.get(i);
19672            long pss = Debug.getPss(st.pid, null, memtrackTmp);
19673            if (pss > 0) {
19674                if (infoMap.indexOfKey(st.pid) < 0) {
19675                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
19676                            ProcessList.NATIVE_ADJ, -1, "native", null);
19677                    mi.pss = pss;
19678                    mi.memtrack = memtrackTmp[0];
19679                    memInfos.add(mi);
19680                }
19681            }
19682        }
19683
19684        long totalPss = 0;
19685        long totalMemtrack = 0;
19686        for (int i=0, N=memInfos.size(); i<N; i++) {
19687            ProcessMemInfo mi = memInfos.get(i);
19688            if (mi.pss == 0) {
19689                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
19690                mi.memtrack = memtrackTmp[0];
19691            }
19692            totalPss += mi.pss;
19693            totalMemtrack += mi.memtrack;
19694        }
19695        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
19696            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
19697                if (lhs.oomAdj != rhs.oomAdj) {
19698                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
19699                }
19700                if (lhs.pss != rhs.pss) {
19701                    return lhs.pss < rhs.pss ? 1 : -1;
19702                }
19703                return 0;
19704            }
19705        });
19706
19707        StringBuilder tag = new StringBuilder(128);
19708        StringBuilder stack = new StringBuilder(128);
19709        tag.append("Low on memory -- ");
19710        appendMemBucket(tag, totalPss, "total", false);
19711        appendMemBucket(stack, totalPss, "total", true);
19712
19713        StringBuilder fullNativeBuilder = new StringBuilder(1024);
19714        StringBuilder shortNativeBuilder = new StringBuilder(1024);
19715        StringBuilder fullJavaBuilder = new StringBuilder(1024);
19716
19717        boolean firstLine = true;
19718        int lastOomAdj = Integer.MIN_VALUE;
19719        long extraNativeRam = 0;
19720        long extraNativeMemtrack = 0;
19721        long cachedPss = 0;
19722        for (int i=0, N=memInfos.size(); i<N; i++) {
19723            ProcessMemInfo mi = memInfos.get(i);
19724
19725            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19726                cachedPss += mi.pss;
19727            }
19728
19729            if (mi.oomAdj != ProcessList.NATIVE_ADJ
19730                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
19731                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
19732                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
19733                if (lastOomAdj != mi.oomAdj) {
19734                    lastOomAdj = mi.oomAdj;
19735                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19736                        tag.append(" / ");
19737                    }
19738                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
19739                        if (firstLine) {
19740                            stack.append(":");
19741                            firstLine = false;
19742                        }
19743                        stack.append("\n\t at ");
19744                    } else {
19745                        stack.append("$");
19746                    }
19747                } else {
19748                    tag.append(" ");
19749                    stack.append("$");
19750                }
19751                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19752                    appendMemBucket(tag, mi.pss, mi.name, false);
19753                }
19754                appendMemBucket(stack, mi.pss, mi.name, true);
19755                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
19756                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
19757                    stack.append("(");
19758                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
19759                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
19760                            stack.append(DUMP_MEM_OOM_LABEL[k]);
19761                            stack.append(":");
19762                            stack.append(DUMP_MEM_OOM_ADJ[k]);
19763                        }
19764                    }
19765                    stack.append(")");
19766                }
19767            }
19768
19769            appendMemInfo(fullNativeBuilder, mi);
19770            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
19771                // The short form only has native processes that are >= 512K.
19772                if (mi.pss >= 512) {
19773                    appendMemInfo(shortNativeBuilder, mi);
19774                } else {
19775                    extraNativeRam += mi.pss;
19776                    extraNativeMemtrack += mi.memtrack;
19777                }
19778            } else {
19779                // Short form has all other details, but if we have collected RAM
19780                // from smaller native processes let's dump a summary of that.
19781                if (extraNativeRam > 0) {
19782                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
19783                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
19784                    shortNativeBuilder.append('\n');
19785                    extraNativeRam = 0;
19786                }
19787                appendMemInfo(fullJavaBuilder, mi);
19788            }
19789        }
19790
19791        fullJavaBuilder.append("           ");
19792        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
19793        fullJavaBuilder.append(": TOTAL");
19794        if (totalMemtrack > 0) {
19795            fullJavaBuilder.append(" (");
19796            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
19797            fullJavaBuilder.append(" memtrack)");
19798        } else {
19799        }
19800        fullJavaBuilder.append("\n");
19801
19802        MemInfoReader memInfo = new MemInfoReader();
19803        memInfo.readMemInfo();
19804        final long[] infos = memInfo.getRawInfo();
19805
19806        StringBuilder memInfoBuilder = new StringBuilder(1024);
19807        Debug.getMemInfo(infos);
19808        memInfoBuilder.append("  MemInfo: ");
19809        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
19810        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
19811        memInfoBuilder.append(stringifyKBSize(
19812                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
19813        memInfoBuilder.append(stringifyKBSize(
19814                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
19815        memInfoBuilder.append(stringifyKBSize(
19816                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
19817        memInfoBuilder.append("           ");
19818        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
19819        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
19820        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
19821        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
19822        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
19823            memInfoBuilder.append("  ZRAM: ");
19824            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
19825            memInfoBuilder.append(" RAM, ");
19826            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
19827            memInfoBuilder.append(" swap total, ");
19828            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
19829            memInfoBuilder.append(" swap free\n");
19830        }
19831        final long[] ksm = getKsmInfo();
19832        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
19833                || ksm[KSM_VOLATILE] != 0) {
19834            memInfoBuilder.append("  KSM: ");
19835            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
19836            memInfoBuilder.append(" saved from shared ");
19837            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
19838            memInfoBuilder.append("\n       ");
19839            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
19840            memInfoBuilder.append(" unshared; ");
19841            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
19842            memInfoBuilder.append(" volatile\n");
19843        }
19844        memInfoBuilder.append("  Free RAM: ");
19845        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19846                + memInfo.getFreeSizeKb()));
19847        memInfoBuilder.append("\n");
19848        memInfoBuilder.append("  Used RAM: ");
19849        memInfoBuilder.append(stringifyKBSize(
19850                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
19851        memInfoBuilder.append("\n");
19852        memInfoBuilder.append("  Lost RAM: ");
19853        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
19854                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19855                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
19856        memInfoBuilder.append("\n");
19857        Slog.i(TAG, "Low on memory:");
19858        Slog.i(TAG, shortNativeBuilder.toString());
19859        Slog.i(TAG, fullJavaBuilder.toString());
19860        Slog.i(TAG, memInfoBuilder.toString());
19861
19862        StringBuilder dropBuilder = new StringBuilder(1024);
19863        /*
19864        StringWriter oomSw = new StringWriter();
19865        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
19866        StringWriter catSw = new StringWriter();
19867        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19868        String[] emptyArgs = new String[] { };
19869        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
19870        oomPw.flush();
19871        String oomString = oomSw.toString();
19872        */
19873        dropBuilder.append("Low on memory:");
19874        dropBuilder.append(stack);
19875        dropBuilder.append('\n');
19876        dropBuilder.append(fullNativeBuilder);
19877        dropBuilder.append(fullJavaBuilder);
19878        dropBuilder.append('\n');
19879        dropBuilder.append(memInfoBuilder);
19880        dropBuilder.append('\n');
19881        /*
19882        dropBuilder.append(oomString);
19883        dropBuilder.append('\n');
19884        */
19885        StringWriter catSw = new StringWriter();
19886        synchronized (ActivityManagerService.this) {
19887            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19888            String[] emptyArgs = new String[] { };
19889            catPw.println();
19890            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
19891            catPw.println();
19892            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
19893                    false, null).dumpLocked();
19894            catPw.println();
19895            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
19896            catPw.flush();
19897        }
19898        dropBuilder.append(catSw.toString());
19899        StatsLog.write(StatsLog.LOW_MEM_REPORTED);
19900        addErrorToDropBox("lowmem", null, "system_server", null,
19901                null, tag.toString(), dropBuilder.toString(), null, null);
19902        //Slog.i(TAG, "Sent to dropbox:");
19903        //Slog.i(TAG, dropBuilder.toString());
19904        synchronized (ActivityManagerService.this) {
19905            long now = SystemClock.uptimeMillis();
19906            if (mLastMemUsageReportTime < now) {
19907                mLastMemUsageReportTime = now;
19908            }
19909        }
19910    }
19911
19912    /**
19913     * Searches array of arguments for the specified string
19914     * @param args array of argument strings
19915     * @param value value to search for
19916     * @return true if the value is contained in the array
19917     */
19918    private static boolean scanArgs(String[] args, String value) {
19919        if (args != null) {
19920            for (String arg : args) {
19921                if (value.equals(arg)) {
19922                    return true;
19923                }
19924            }
19925        }
19926        return false;
19927    }
19928
19929    private final boolean removeDyingProviderLocked(ProcessRecord proc,
19930            ContentProviderRecord cpr, boolean always) {
19931        final boolean inLaunching = mLaunchingProviders.contains(cpr);
19932
19933        if (!inLaunching || always) {
19934            synchronized (cpr) {
19935                cpr.launchingApp = null;
19936                cpr.notifyAll();
19937            }
19938            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
19939            String names[] = cpr.info.authority.split(";");
19940            for (int j = 0; j < names.length; j++) {
19941                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
19942            }
19943        }
19944
19945        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
19946            ContentProviderConnection conn = cpr.connections.get(i);
19947            if (conn.waiting) {
19948                // If this connection is waiting for the provider, then we don't
19949                // need to mess with its process unless we are always removing
19950                // or for some reason the provider is not currently launching.
19951                if (inLaunching && !always) {
19952                    continue;
19953                }
19954            }
19955            ProcessRecord capp = conn.client;
19956            conn.dead = true;
19957            if (conn.stableCount > 0) {
19958                if (!capp.persistent && capp.thread != null
19959                        && capp.pid != 0
19960                        && capp.pid != MY_PID) {
19961                    capp.kill("depends on provider "
19962                            + cpr.name.flattenToShortString()
19963                            + " in dying proc " + (proc != null ? proc.processName : "??")
19964                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
19965                }
19966            } else if (capp.thread != null && conn.provider.provider != null) {
19967                try {
19968                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
19969                } catch (RemoteException e) {
19970                }
19971                // In the protocol here, we don't expect the client to correctly
19972                // clean up this connection, we'll just remove it.
19973                cpr.connections.remove(i);
19974                if (conn.client.conProviders.remove(conn)) {
19975                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
19976                }
19977            }
19978        }
19979
19980        if (inLaunching && always) {
19981            mLaunchingProviders.remove(cpr);
19982        }
19983        return inLaunching;
19984    }
19985
19986    /**
19987     * Main code for cleaning up a process when it has gone away.  This is
19988     * called both as a result of the process dying, or directly when stopping
19989     * a process when running in single process mode.
19990     *
19991     * @return Returns true if the given process has been restarted, so the
19992     * app that was passed in must remain on the process lists.
19993     */
19994    @GuardedBy("this")
19995    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
19996            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
19997        if (index >= 0) {
19998            removeLruProcessLocked(app);
19999            ProcessList.remove(app.pid);
20000        }
20001
20002        mProcessesToGc.remove(app);
20003        mPendingPssProcesses.remove(app);
20004        ProcessList.abortNextPssTime(app.procStateMemTracker);
20005
20006        // Dismiss any open dialogs.
20007        if (app.crashDialog != null && !app.forceCrashReport) {
20008            app.crashDialog.dismiss();
20009            app.crashDialog = null;
20010        }
20011        if (app.anrDialog != null) {
20012            app.anrDialog.dismiss();
20013            app.anrDialog = null;
20014        }
20015        if (app.waitDialog != null) {
20016            app.waitDialog.dismiss();
20017            app.waitDialog = null;
20018        }
20019
20020        app.crashing = false;
20021        app.notResponding = false;
20022
20023        app.resetPackageList(mProcessStats);
20024        app.unlinkDeathRecipient();
20025        app.makeInactive(mProcessStats);
20026        app.waitingToKill = null;
20027        app.forcingToImportant = null;
20028        updateProcessForegroundLocked(app, false, false);
20029        app.foregroundActivities = false;
20030        app.hasShownUi = false;
20031        app.treatLikeActivity = false;
20032        app.hasAboveClient = false;
20033        app.hasClientActivities = false;
20034
20035        mServices.killServicesLocked(app, allowRestart);
20036
20037        boolean restart = false;
20038
20039        // Remove published content providers.
20040        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
20041            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
20042            final boolean always = app.bad || !allowRestart;
20043            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
20044            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
20045                // We left the provider in the launching list, need to
20046                // restart it.
20047                restart = true;
20048            }
20049
20050            cpr.provider = null;
20051            cpr.proc = null;
20052        }
20053        app.pubProviders.clear();
20054
20055        // Take care of any launching providers waiting for this process.
20056        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
20057            restart = true;
20058        }
20059
20060        // Unregister from connected content providers.
20061        if (!app.conProviders.isEmpty()) {
20062            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
20063                ContentProviderConnection conn = app.conProviders.get(i);
20064                conn.provider.connections.remove(conn);
20065                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
20066                        conn.provider.name);
20067            }
20068            app.conProviders.clear();
20069        }
20070
20071        // At this point there may be remaining entries in mLaunchingProviders
20072        // where we were the only one waiting, so they are no longer of use.
20073        // Look for these and clean up if found.
20074        // XXX Commented out for now.  Trying to figure out a way to reproduce
20075        // the actual situation to identify what is actually going on.
20076        if (false) {
20077            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20078                ContentProviderRecord cpr = mLaunchingProviders.get(i);
20079                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
20080                    synchronized (cpr) {
20081                        cpr.launchingApp = null;
20082                        cpr.notifyAll();
20083                    }
20084                }
20085            }
20086        }
20087
20088        skipCurrentReceiverLocked(app);
20089
20090        // Unregister any receivers.
20091        for (int i = app.receivers.size() - 1; i >= 0; i--) {
20092            removeReceiverLocked(app.receivers.valueAt(i));
20093        }
20094        app.receivers.clear();
20095
20096        // If the app is undergoing backup, tell the backup manager about it
20097        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
20098            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
20099                    + mBackupTarget.appInfo + " died during backup");
20100            mHandler.post(new Runnable() {
20101                @Override
20102                public void run(){
20103                    try {
20104                        IBackupManager bm = IBackupManager.Stub.asInterface(
20105                                ServiceManager.getService(Context.BACKUP_SERVICE));
20106                        bm.agentDisconnected(app.info.packageName);
20107                    } catch (RemoteException e) {
20108                        // can't happen; backup manager is local
20109                    }
20110                }
20111            });
20112        }
20113
20114        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
20115            ProcessChangeItem item = mPendingProcessChanges.get(i);
20116            if (app.pid > 0 && item.pid == app.pid) {
20117                mPendingProcessChanges.remove(i);
20118                mAvailProcessChanges.add(item);
20119            }
20120        }
20121        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
20122                null).sendToTarget();
20123
20124        // If the caller is restarting this app, then leave it in its
20125        // current lists and let the caller take care of it.
20126        if (restarting) {
20127            return false;
20128        }
20129
20130        if (!app.persistent || app.isolated) {
20131            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
20132                    "Removing non-persistent process during cleanup: " + app);
20133            if (!replacingPid) {
20134                removeProcessNameLocked(app.processName, app.uid, app);
20135            }
20136            if (mHeavyWeightProcess == app) {
20137                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
20138                        mHeavyWeightProcess.userId, 0));
20139                mHeavyWeightProcess = null;
20140            }
20141        } else if (!app.removed) {
20142            // This app is persistent, so we need to keep its record around.
20143            // If it is not already on the pending app list, add it there
20144            // and start a new process for it.
20145            if (mPersistentStartingProcesses.indexOf(app) < 0) {
20146                mPersistentStartingProcesses.add(app);
20147                restart = true;
20148            }
20149        }
20150        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
20151                TAG_CLEANUP, "Clean-up removing on hold: " + app);
20152        mProcessesOnHold.remove(app);
20153
20154        if (app == mHomeProcess) {
20155            mHomeProcess = null;
20156        }
20157        if (app == mPreviousProcess) {
20158            mPreviousProcess = null;
20159        }
20160
20161        if (restart && !app.isolated) {
20162            // We have components that still need to be running in the
20163            // process, so re-launch it.
20164            if (index < 0) {
20165                ProcessList.remove(app.pid);
20166            }
20167            addProcessNameLocked(app);
20168            app.pendingStart = false;
20169            startProcessLocked(app, "restart", app.processName);
20170            return true;
20171        } else if (app.pid > 0 && app.pid != MY_PID) {
20172            // Goodbye!
20173            boolean removed;
20174            synchronized (mPidsSelfLocked) {
20175                mPidsSelfLocked.remove(app.pid);
20176                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
20177            }
20178            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
20179            if (app.isolated) {
20180                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
20181            }
20182            app.setPid(0);
20183        }
20184        return false;
20185    }
20186
20187    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
20188        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20189            ContentProviderRecord cpr = mLaunchingProviders.get(i);
20190            if (cpr.launchingApp == app) {
20191                return true;
20192            }
20193        }
20194        return false;
20195    }
20196
20197    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
20198        // Look through the content providers we are waiting to have launched,
20199        // and if any run in this process then either schedule a restart of
20200        // the process or kill the client waiting for it if this process has
20201        // gone bad.
20202        boolean restart = false;
20203        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20204            ContentProviderRecord cpr = mLaunchingProviders.get(i);
20205            if (cpr.launchingApp == app) {
20206                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
20207                    restart = true;
20208                } else {
20209                    removeDyingProviderLocked(app, cpr, true);
20210                }
20211            }
20212        }
20213        return restart;
20214    }
20215
20216    // =========================================================
20217    // SERVICES
20218    // =========================================================
20219
20220    @Override
20221    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
20222        enforceNotIsolatedCaller("getServices");
20223
20224        final int callingUid = Binder.getCallingUid();
20225        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
20226            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
20227        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
20228            callingUid);
20229        synchronized (this) {
20230            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
20231                allowed, canInteractAcrossUsers);
20232        }
20233    }
20234
20235    @Override
20236    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
20237        enforceNotIsolatedCaller("getRunningServiceControlPanel");
20238        synchronized (this) {
20239            return mServices.getRunningServiceControlPanelLocked(name);
20240        }
20241    }
20242
20243    @Override
20244    public ComponentName startService(IApplicationThread caller, Intent service,
20245            String resolvedType, boolean requireForeground, String callingPackage, int userId)
20246            throws TransactionTooLargeException {
20247        enforceNotIsolatedCaller("startService");
20248        // Refuse possible leaked file descriptors
20249        if (service != null && service.hasFileDescriptors() == true) {
20250            throw new IllegalArgumentException("File descriptors passed in Intent");
20251        }
20252
20253        if (callingPackage == null) {
20254            throw new IllegalArgumentException("callingPackage cannot be null");
20255        }
20256
20257        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20258                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
20259        synchronized(this) {
20260            final int callingPid = Binder.getCallingPid();
20261            final int callingUid = Binder.getCallingUid();
20262            final long origId = Binder.clearCallingIdentity();
20263            ComponentName res;
20264            try {
20265                res = mServices.startServiceLocked(caller, service,
20266                        resolvedType, callingPid, callingUid,
20267                        requireForeground, callingPackage, userId);
20268            } finally {
20269                Binder.restoreCallingIdentity(origId);
20270            }
20271            return res;
20272        }
20273    }
20274
20275    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
20276            boolean fgRequired, String callingPackage, int userId)
20277            throws TransactionTooLargeException {
20278        synchronized(this) {
20279            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20280                    "startServiceInPackage: " + service + " type=" + resolvedType);
20281            final long origId = Binder.clearCallingIdentity();
20282            ComponentName res;
20283            try {
20284                res = mServices.startServiceLocked(null, service,
20285                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
20286            } finally {
20287                Binder.restoreCallingIdentity(origId);
20288            }
20289            return res;
20290        }
20291    }
20292
20293    @Override
20294    public int stopService(IApplicationThread caller, Intent service,
20295            String resolvedType, int userId) {
20296        enforceNotIsolatedCaller("stopService");
20297        // Refuse possible leaked file descriptors
20298        if (service != null && service.hasFileDescriptors() == true) {
20299            throw new IllegalArgumentException("File descriptors passed in Intent");
20300        }
20301
20302        synchronized(this) {
20303            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
20304        }
20305    }
20306
20307    @Override
20308    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
20309        enforceNotIsolatedCaller("peekService");
20310        // Refuse possible leaked file descriptors
20311        if (service != null && service.hasFileDescriptors() == true) {
20312            throw new IllegalArgumentException("File descriptors passed in Intent");
20313        }
20314
20315        if (callingPackage == null) {
20316            throw new IllegalArgumentException("callingPackage cannot be null");
20317        }
20318
20319        synchronized(this) {
20320            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
20321        }
20322    }
20323
20324    @Override
20325    public boolean stopServiceToken(ComponentName className, IBinder token,
20326            int startId) {
20327        synchronized(this) {
20328            return mServices.stopServiceTokenLocked(className, token, startId);
20329        }
20330    }
20331
20332    @Override
20333    public void setServiceForeground(ComponentName className, IBinder token,
20334            int id, Notification notification, int flags) {
20335        synchronized(this) {
20336            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
20337        }
20338    }
20339
20340    @Override
20341    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
20342            boolean requireFull, String name, String callerPackage) {
20343        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
20344                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
20345    }
20346
20347    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
20348            String className, int flags) {
20349        boolean result = false;
20350        // For apps that don't have pre-defined UIDs, check for permission
20351        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
20352            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20353                if (ActivityManager.checkUidPermission(
20354                        INTERACT_ACROSS_USERS,
20355                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
20356                    ComponentName comp = new ComponentName(aInfo.packageName, className);
20357                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
20358                            + " requests FLAG_SINGLE_USER, but app does not hold "
20359                            + INTERACT_ACROSS_USERS;
20360                    Slog.w(TAG, msg);
20361                    throw new SecurityException(msg);
20362                }
20363                // Permission passed
20364                result = true;
20365            }
20366        } else if ("system".equals(componentProcessName)) {
20367            result = true;
20368        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20369            // Phone app and persistent apps are allowed to export singleuser providers.
20370            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
20371                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
20372        }
20373        if (DEBUG_MU) Slog.v(TAG_MU,
20374                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
20375                + Integer.toHexString(flags) + ") = " + result);
20376        return result;
20377    }
20378
20379    /**
20380     * Checks to see if the caller is in the same app as the singleton
20381     * component, or the component is in a special app. It allows special apps
20382     * to export singleton components but prevents exporting singleton
20383     * components for regular apps.
20384     */
20385    boolean isValidSingletonCall(int callingUid, int componentUid) {
20386        int componentAppId = UserHandle.getAppId(componentUid);
20387        return UserHandle.isSameApp(callingUid, componentUid)
20388                || componentAppId == SYSTEM_UID
20389                || componentAppId == PHONE_UID
20390                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
20391                        == PackageManager.PERMISSION_GRANTED;
20392    }
20393
20394    public int bindService(IApplicationThread caller, IBinder token, Intent service,
20395            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
20396            int userId) throws TransactionTooLargeException {
20397        enforceNotIsolatedCaller("bindService");
20398
20399        // Refuse possible leaked file descriptors
20400        if (service != null && service.hasFileDescriptors() == true) {
20401            throw new IllegalArgumentException("File descriptors passed in Intent");
20402        }
20403
20404        if (callingPackage == null) {
20405            throw new IllegalArgumentException("callingPackage cannot be null");
20406        }
20407
20408        synchronized(this) {
20409            return mServices.bindServiceLocked(caller, token, service,
20410                    resolvedType, connection, flags, callingPackage, userId);
20411        }
20412    }
20413
20414    public boolean unbindService(IServiceConnection connection) {
20415        synchronized (this) {
20416            return mServices.unbindServiceLocked(connection);
20417        }
20418    }
20419
20420    public void publishService(IBinder token, Intent intent, IBinder service) {
20421        // Refuse possible leaked file descriptors
20422        if (intent != null && intent.hasFileDescriptors() == true) {
20423            throw new IllegalArgumentException("File descriptors passed in Intent");
20424        }
20425
20426        synchronized(this) {
20427            if (!(token instanceof ServiceRecord)) {
20428                throw new IllegalArgumentException("Invalid service token");
20429            }
20430            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
20431        }
20432    }
20433
20434    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
20435        // Refuse possible leaked file descriptors
20436        if (intent != null && intent.hasFileDescriptors() == true) {
20437            throw new IllegalArgumentException("File descriptors passed in Intent");
20438        }
20439
20440        synchronized(this) {
20441            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
20442        }
20443    }
20444
20445    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
20446        synchronized(this) {
20447            if (!(token instanceof ServiceRecord)) {
20448                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
20449                throw new IllegalArgumentException("Invalid service token");
20450            }
20451            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
20452        }
20453    }
20454
20455    // =========================================================
20456    // BACKUP AND RESTORE
20457    // =========================================================
20458
20459    // Cause the target app to be launched if necessary and its backup agent
20460    // instantiated.  The backup agent will invoke backupAgentCreated() on the
20461    // activity manager to announce its creation.
20462    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
20463        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
20464        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
20465
20466        IPackageManager pm = AppGlobals.getPackageManager();
20467        ApplicationInfo app = null;
20468        try {
20469            app = pm.getApplicationInfo(packageName, 0, userId);
20470        } catch (RemoteException e) {
20471            // can't happen; package manager is process-local
20472        }
20473        if (app == null) {
20474            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
20475            return false;
20476        }
20477
20478        int oldBackupUid;
20479        int newBackupUid;
20480
20481        synchronized(this) {
20482            // !!! TODO: currently no check here that we're already bound
20483            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
20484            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20485            synchronized (stats) {
20486                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
20487            }
20488
20489            // Backup agent is now in use, its package can't be stopped.
20490            try {
20491                AppGlobals.getPackageManager().setPackageStoppedState(
20492                        app.packageName, false, UserHandle.getUserId(app.uid));
20493            } catch (RemoteException e) {
20494            } catch (IllegalArgumentException e) {
20495                Slog.w(TAG, "Failed trying to unstop package "
20496                        + app.packageName + ": " + e);
20497            }
20498
20499            BackupRecord r = new BackupRecord(ss, app, backupMode);
20500            ComponentName hostingName =
20501                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
20502                            ? new ComponentName(app.packageName, app.backupAgentName)
20503                            : new ComponentName("android", "FullBackupAgent");
20504            // startProcessLocked() returns existing proc's record if it's already running
20505            ProcessRecord proc = startProcessLocked(app.processName, app,
20506                    false, 0, "backup", hostingName, false, false, false);
20507            if (proc == null) {
20508                Slog.e(TAG, "Unable to start backup agent process " + r);
20509                return false;
20510            }
20511
20512            // If the app is a regular app (uid >= 10000) and not the system server or phone
20513            // process, etc, then mark it as being in full backup so that certain calls to the
20514            // process can be blocked. This is not reset to false anywhere because we kill the
20515            // process after the full backup is done and the ProcessRecord will vaporize anyway.
20516            if (UserHandle.isApp(app.uid) &&
20517                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
20518                proc.inFullBackup = true;
20519            }
20520            r.app = proc;
20521            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20522            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
20523            mBackupTarget = r;
20524            mBackupAppName = app.packageName;
20525
20526            // Try not to kill the process during backup
20527            updateOomAdjLocked(proc, true);
20528
20529            // If the process is already attached, schedule the creation of the backup agent now.
20530            // If it is not yet live, this will be done when it attaches to the framework.
20531            if (proc.thread != null) {
20532                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
20533                try {
20534                    proc.thread.scheduleCreateBackupAgent(app,
20535                            compatibilityInfoForPackageLocked(app), backupMode);
20536                } catch (RemoteException e) {
20537                    // Will time out on the backup manager side
20538                }
20539            } else {
20540                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
20541            }
20542            // Invariants: at this point, the target app process exists and the application
20543            // is either already running or in the process of coming up.  mBackupTarget and
20544            // mBackupAppName describe the app, so that when it binds back to the AM we
20545            // know that it's scheduled for a backup-agent operation.
20546        }
20547
20548        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20549        if (oldBackupUid != -1) {
20550            js.removeBackingUpUid(oldBackupUid);
20551        }
20552        if (newBackupUid != -1) {
20553            js.addBackingUpUid(newBackupUid);
20554        }
20555
20556        return true;
20557    }
20558
20559    @Override
20560    public void clearPendingBackup() {
20561        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
20562        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
20563
20564        synchronized (this) {
20565            mBackupTarget = null;
20566            mBackupAppName = null;
20567        }
20568
20569        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20570        js.clearAllBackingUpUids();
20571    }
20572
20573    // A backup agent has just come up
20574    public void backupAgentCreated(String agentPackageName, IBinder agent) {
20575        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
20576                + " = " + agent);
20577
20578        synchronized(this) {
20579            if (!agentPackageName.equals(mBackupAppName)) {
20580                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
20581                return;
20582            }
20583        }
20584
20585        long oldIdent = Binder.clearCallingIdentity();
20586        try {
20587            IBackupManager bm = IBackupManager.Stub.asInterface(
20588                    ServiceManager.getService(Context.BACKUP_SERVICE));
20589            bm.agentConnected(agentPackageName, agent);
20590        } catch (RemoteException e) {
20591            // can't happen; the backup manager service is local
20592        } catch (Exception e) {
20593            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
20594            e.printStackTrace();
20595        } finally {
20596            Binder.restoreCallingIdentity(oldIdent);
20597        }
20598    }
20599
20600    // done with this agent
20601    public void unbindBackupAgent(ApplicationInfo appInfo) {
20602        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
20603        if (appInfo == null) {
20604            Slog.w(TAG, "unbind backup agent for null app");
20605            return;
20606        }
20607
20608        int oldBackupUid;
20609
20610        synchronized(this) {
20611            try {
20612                if (mBackupAppName == null) {
20613                    Slog.w(TAG, "Unbinding backup agent with no active backup");
20614                    return;
20615                }
20616
20617                if (!mBackupAppName.equals(appInfo.packageName)) {
20618                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
20619                    return;
20620                }
20621
20622                // Not backing this app up any more; reset its OOM adjustment
20623                final ProcessRecord proc = mBackupTarget.app;
20624                updateOomAdjLocked(proc, true);
20625                proc.inFullBackup = false;
20626
20627                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20628
20629                // If the app crashed during backup, 'thread' will be null here
20630                if (proc.thread != null) {
20631                    try {
20632                        proc.thread.scheduleDestroyBackupAgent(appInfo,
20633                                compatibilityInfoForPackageLocked(appInfo));
20634                    } catch (Exception e) {
20635                        Slog.e(TAG, "Exception when unbinding backup agent:");
20636                        e.printStackTrace();
20637                    }
20638                }
20639            } finally {
20640                mBackupTarget = null;
20641                mBackupAppName = null;
20642            }
20643        }
20644
20645        if (oldBackupUid != -1) {
20646            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20647            js.removeBackingUpUid(oldBackupUid);
20648        }
20649    }
20650
20651    // =========================================================
20652    // BROADCASTS
20653    // =========================================================
20654
20655    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
20656        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
20657            return false;
20658        }
20659        // Easy case -- we have the app's ProcessRecord.
20660        if (record != null) {
20661            return record.info.isInstantApp();
20662        }
20663        // Otherwise check with PackageManager.
20664        if (callerPackage == null) {
20665            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
20666            throw new IllegalArgumentException("Calling application did not provide package name");
20667        }
20668        mAppOpsService.checkPackage(uid, callerPackage);
20669        try {
20670            IPackageManager pm = AppGlobals.getPackageManager();
20671            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
20672        } catch (RemoteException e) {
20673            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
20674            return true;
20675        }
20676    }
20677
20678    boolean isPendingBroadcastProcessLocked(int pid) {
20679        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
20680                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
20681    }
20682
20683    void skipPendingBroadcastLocked(int pid) {
20684            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
20685            for (BroadcastQueue queue : mBroadcastQueues) {
20686                queue.skipPendingBroadcastLocked(pid);
20687            }
20688    }
20689
20690    // The app just attached; send any pending broadcasts that it should receive
20691    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
20692        boolean didSomething = false;
20693        for (BroadcastQueue queue : mBroadcastQueues) {
20694            didSomething |= queue.sendPendingBroadcastsLocked(app);
20695        }
20696        return didSomething;
20697    }
20698
20699    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
20700            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
20701            int flags) {
20702        enforceNotIsolatedCaller("registerReceiver");
20703        ArrayList<Intent> stickyIntents = null;
20704        ProcessRecord callerApp = null;
20705        final boolean visibleToInstantApps
20706                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
20707        int callingUid;
20708        int callingPid;
20709        boolean instantApp;
20710        synchronized(this) {
20711            if (caller != null) {
20712                callerApp = getRecordForAppLocked(caller);
20713                if (callerApp == null) {
20714                    throw new SecurityException(
20715                            "Unable to find app for caller " + caller
20716                            + " (pid=" + Binder.getCallingPid()
20717                            + ") when registering receiver " + receiver);
20718                }
20719                if (callerApp.info.uid != SYSTEM_UID &&
20720                        !callerApp.pkgList.containsKey(callerPackage) &&
20721                        !"android".equals(callerPackage)) {
20722                    throw new SecurityException("Given caller package " + callerPackage
20723                            + " is not running in process " + callerApp);
20724                }
20725                callingUid = callerApp.info.uid;
20726                callingPid = callerApp.pid;
20727            } else {
20728                callerPackage = null;
20729                callingUid = Binder.getCallingUid();
20730                callingPid = Binder.getCallingPid();
20731            }
20732
20733            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
20734            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20735                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
20736
20737            Iterator<String> actions = filter.actionsIterator();
20738            if (actions == null) {
20739                ArrayList<String> noAction = new ArrayList<String>(1);
20740                noAction.add(null);
20741                actions = noAction.iterator();
20742            }
20743
20744            // Collect stickies of users
20745            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
20746            while (actions.hasNext()) {
20747                String action = actions.next();
20748                for (int id : userIds) {
20749                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
20750                    if (stickies != null) {
20751                        ArrayList<Intent> intents = stickies.get(action);
20752                        if (intents != null) {
20753                            if (stickyIntents == null) {
20754                                stickyIntents = new ArrayList<Intent>();
20755                            }
20756                            stickyIntents.addAll(intents);
20757                        }
20758                    }
20759                }
20760            }
20761        }
20762
20763        ArrayList<Intent> allSticky = null;
20764        if (stickyIntents != null) {
20765            final ContentResolver resolver = mContext.getContentResolver();
20766            // Look for any matching sticky broadcasts...
20767            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
20768                Intent intent = stickyIntents.get(i);
20769                // Don't provided intents that aren't available to instant apps.
20770                if (instantApp &&
20771                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
20772                    continue;
20773                }
20774                // If intent has scheme "content", it will need to acccess
20775                // provider that needs to lock mProviderMap in ActivityThread
20776                // and also it may need to wait application response, so we
20777                // cannot lock ActivityManagerService here.
20778                if (filter.match(resolver, intent, true, TAG) >= 0) {
20779                    if (allSticky == null) {
20780                        allSticky = new ArrayList<Intent>();
20781                    }
20782                    allSticky.add(intent);
20783                }
20784            }
20785        }
20786
20787        // The first sticky in the list is returned directly back to the client.
20788        Intent sticky = allSticky != null ? allSticky.get(0) : null;
20789        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
20790        if (receiver == null) {
20791            return sticky;
20792        }
20793
20794        synchronized (this) {
20795            if (callerApp != null && (callerApp.thread == null
20796                    || callerApp.thread.asBinder() != caller.asBinder())) {
20797                // Original caller already died
20798                return null;
20799            }
20800            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20801            if (rl == null) {
20802                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
20803                        userId, receiver);
20804                if (rl.app != null) {
20805                    final int totalReceiversForApp = rl.app.receivers.size();
20806                    if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
20807                        throw new IllegalStateException("Too many receivers, total of "
20808                                + totalReceiversForApp + ", registered for pid: "
20809                                + rl.pid + ", callerPackage: " + callerPackage);
20810                    }
20811                    rl.app.receivers.add(rl);
20812                } else {
20813                    try {
20814                        receiver.asBinder().linkToDeath(rl, 0);
20815                    } catch (RemoteException e) {
20816                        return sticky;
20817                    }
20818                    rl.linkedToDeath = true;
20819                }
20820                mRegisteredReceivers.put(receiver.asBinder(), rl);
20821            } else if (rl.uid != callingUid) {
20822                throw new IllegalArgumentException(
20823                        "Receiver requested to register for uid " + callingUid
20824                        + " was previously registered for uid " + rl.uid
20825                        + " callerPackage is " + callerPackage);
20826            } else if (rl.pid != callingPid) {
20827                throw new IllegalArgumentException(
20828                        "Receiver requested to register for pid " + callingPid
20829                        + " was previously registered for pid " + rl.pid
20830                        + " callerPackage is " + callerPackage);
20831            } else if (rl.userId != userId) {
20832                throw new IllegalArgumentException(
20833                        "Receiver requested to register for user " + userId
20834                        + " was previously registered for user " + rl.userId
20835                        + " callerPackage is " + callerPackage);
20836            }
20837            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
20838                    permission, callingUid, userId, instantApp, visibleToInstantApps);
20839            if (rl.containsFilter(filter)) {
20840                Slog.w(TAG, "Receiver with filter " + filter
20841                        + " already registered for pid " + rl.pid
20842                        + ", callerPackage is " + callerPackage);
20843            } else {
20844                rl.add(bf);
20845                if (!bf.debugCheck()) {
20846                    Slog.w(TAG, "==> For Dynamic broadcast");
20847                }
20848                mReceiverResolver.addFilter(bf);
20849            }
20850
20851            // Enqueue broadcasts for all existing stickies that match
20852            // this filter.
20853            if (allSticky != null) {
20854                ArrayList receivers = new ArrayList();
20855                receivers.add(bf);
20856
20857                final int stickyCount = allSticky.size();
20858                for (int i = 0; i < stickyCount; i++) {
20859                    Intent intent = allSticky.get(i);
20860                    BroadcastQueue queue = broadcastQueueForIntent(intent);
20861                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
20862                            null, -1, -1, false, null, null, OP_NONE, null, receivers,
20863                            null, 0, null, null, false, true, true, -1);
20864                    queue.enqueueParallelBroadcastLocked(r);
20865                    queue.scheduleBroadcastsLocked();
20866                }
20867            }
20868
20869            return sticky;
20870        }
20871    }
20872
20873    public void unregisterReceiver(IIntentReceiver receiver) {
20874        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
20875
20876        final long origId = Binder.clearCallingIdentity();
20877        try {
20878            boolean doTrim = false;
20879
20880            synchronized(this) {
20881                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20882                if (rl != null) {
20883                    final BroadcastRecord r = rl.curBroadcast;
20884                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
20885                        final boolean doNext = r.queue.finishReceiverLocked(
20886                                r, r.resultCode, r.resultData, r.resultExtras,
20887                                r.resultAbort, false);
20888                        if (doNext) {
20889                            doTrim = true;
20890                            r.queue.processNextBroadcast(false);
20891                        }
20892                    }
20893
20894                    if (rl.app != null) {
20895                        rl.app.receivers.remove(rl);
20896                    }
20897                    removeReceiverLocked(rl);
20898                    if (rl.linkedToDeath) {
20899                        rl.linkedToDeath = false;
20900                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
20901                    }
20902                }
20903            }
20904
20905            // If we actually concluded any broadcasts, we might now be able
20906            // to trim the recipients' apps from our working set
20907            if (doTrim) {
20908                trimApplications();
20909                return;
20910            }
20911
20912        } finally {
20913            Binder.restoreCallingIdentity(origId);
20914        }
20915    }
20916
20917    void removeReceiverLocked(ReceiverList rl) {
20918        mRegisteredReceivers.remove(rl.receiver.asBinder());
20919        for (int i = rl.size() - 1; i >= 0; i--) {
20920            mReceiverResolver.removeFilter(rl.get(i));
20921        }
20922    }
20923
20924    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
20925        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20926            ProcessRecord r = mLruProcesses.get(i);
20927            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
20928                try {
20929                    r.thread.dispatchPackageBroadcast(cmd, packages);
20930                } catch (RemoteException ex) {
20931                }
20932            }
20933        }
20934    }
20935
20936    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
20937            int callingUid, int[] users) {
20938        // TODO: come back and remove this assumption to triage all broadcasts
20939        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
20940
20941        List<ResolveInfo> receivers = null;
20942        try {
20943            HashSet<ComponentName> singleUserReceivers = null;
20944            boolean scannedFirstReceivers = false;
20945            for (int user : users) {
20946                // Skip users that have Shell restrictions, with exception of always permitted
20947                // Shell broadcasts
20948                if (callingUid == SHELL_UID
20949                        && mUserController.hasUserRestriction(
20950                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
20951                        && !isPermittedShellBroadcast(intent)) {
20952                    continue;
20953                }
20954                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
20955                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
20956                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
20957                    // If this is not the system user, we need to check for
20958                    // any receivers that should be filtered out.
20959                    for (int i=0; i<newReceivers.size(); i++) {
20960                        ResolveInfo ri = newReceivers.get(i);
20961                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
20962                            newReceivers.remove(i);
20963                            i--;
20964                        }
20965                    }
20966                }
20967                if (newReceivers != null && newReceivers.size() == 0) {
20968                    newReceivers = null;
20969                }
20970                if (receivers == null) {
20971                    receivers = newReceivers;
20972                } else if (newReceivers != null) {
20973                    // We need to concatenate the additional receivers
20974                    // found with what we have do far.  This would be easy,
20975                    // but we also need to de-dup any receivers that are
20976                    // singleUser.
20977                    if (!scannedFirstReceivers) {
20978                        // Collect any single user receivers we had already retrieved.
20979                        scannedFirstReceivers = true;
20980                        for (int i=0; i<receivers.size(); i++) {
20981                            ResolveInfo ri = receivers.get(i);
20982                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20983                                ComponentName cn = new ComponentName(
20984                                        ri.activityInfo.packageName, ri.activityInfo.name);
20985                                if (singleUserReceivers == null) {
20986                                    singleUserReceivers = new HashSet<ComponentName>();
20987                                }
20988                                singleUserReceivers.add(cn);
20989                            }
20990                        }
20991                    }
20992                    // Add the new results to the existing results, tracking
20993                    // and de-dupping single user receivers.
20994                    for (int i=0; i<newReceivers.size(); i++) {
20995                        ResolveInfo ri = newReceivers.get(i);
20996                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20997                            ComponentName cn = new ComponentName(
20998                                    ri.activityInfo.packageName, ri.activityInfo.name);
20999                            if (singleUserReceivers == null) {
21000                                singleUserReceivers = new HashSet<ComponentName>();
21001                            }
21002                            if (!singleUserReceivers.contains(cn)) {
21003                                singleUserReceivers.add(cn);
21004                                receivers.add(ri);
21005                            }
21006                        } else {
21007                            receivers.add(ri);
21008                        }
21009                    }
21010                }
21011            }
21012        } catch (RemoteException ex) {
21013            // pm is in same process, this will never happen.
21014        }
21015        return receivers;
21016    }
21017
21018    private boolean isPermittedShellBroadcast(Intent intent) {
21019        // remote bugreport should always be allowed to be taken
21020        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
21021    }
21022
21023    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
21024            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
21025        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21026            // Don't yell about broadcasts sent via shell
21027            return;
21028        }
21029
21030        final String action = intent.getAction();
21031        if (isProtectedBroadcast
21032                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
21033                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
21034                || Intent.ACTION_MEDIA_BUTTON.equals(action)
21035                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
21036                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
21037                || Intent.ACTION_MASTER_CLEAR.equals(action)
21038                || Intent.ACTION_FACTORY_RESET.equals(action)
21039                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
21040                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
21041                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
21042                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
21043                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
21044                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
21045                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
21046            // Broadcast is either protected, or it's a public action that
21047            // we've relaxed, so it's fine for system internals to send.
21048            return;
21049        }
21050
21051        // This broadcast may be a problem...  but there are often system components that
21052        // want to send an internal broadcast to themselves, which is annoying to have to
21053        // explicitly list each action as a protected broadcast, so we will check for that
21054        // one safe case and allow it: an explicit broadcast, only being received by something
21055        // that has protected itself.
21056        if (intent.getPackage() != null || intent.getComponent() != null) {
21057            if (receivers == null || receivers.size() == 0) {
21058                // Intent is explicit and there's no receivers.
21059                // This happens, e.g. , when a system component sends a broadcast to
21060                // its own runtime receiver, and there's no manifest receivers for it,
21061                // because this method is called twice for each broadcast,
21062                // for runtime receivers and manifest receivers and the later check would find
21063                // no receivers.
21064                return;
21065            }
21066            boolean allProtected = true;
21067            for (int i = receivers.size()-1; i >= 0; i--) {
21068                Object target = receivers.get(i);
21069                if (target instanceof ResolveInfo) {
21070                    ResolveInfo ri = (ResolveInfo)target;
21071                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
21072                        allProtected = false;
21073                        break;
21074                    }
21075                } else {
21076                    BroadcastFilter bf = (BroadcastFilter)target;
21077                    if (bf.requiredPermission == null) {
21078                        allProtected = false;
21079                        break;
21080                    }
21081                }
21082            }
21083            if (allProtected) {
21084                // All safe!
21085                return;
21086            }
21087        }
21088
21089        // The vast majority of broadcasts sent from system internals
21090        // should be protected to avoid security holes, so yell loudly
21091        // to ensure we examine these cases.
21092        if (callerApp != null) {
21093            Log.wtf(TAG, "Sending non-protected broadcast " + action
21094                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
21095                    new Throwable());
21096        } else {
21097            Log.wtf(TAG, "Sending non-protected broadcast " + action
21098                            + " from system uid " + UserHandle.formatUid(callingUid)
21099                            + " pkg " + callerPackage,
21100                    new Throwable());
21101        }
21102    }
21103
21104    @GuardedBy("this")
21105    final int broadcastIntentLocked(ProcessRecord callerApp,
21106            String callerPackage, Intent intent, String resolvedType,
21107            IIntentReceiver resultTo, int resultCode, String resultData,
21108            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
21109            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
21110        intent = new Intent(intent);
21111
21112        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
21113        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
21114        if (callerInstantApp) {
21115            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21116        }
21117
21118        // By default broadcasts do not go to stopped apps.
21119        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
21120
21121        // If we have not finished booting, don't allow this to launch new processes.
21122        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
21123            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21124        }
21125
21126        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
21127                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
21128                + " ordered=" + ordered + " userid=" + userId);
21129        if ((resultTo != null) && !ordered) {
21130            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
21131        }
21132
21133        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
21134                ALLOW_NON_FULL, "broadcast", callerPackage);
21135
21136        // Make sure that the user who is receiving this broadcast or its parent is running.
21137        // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
21138        if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
21139            if ((callingUid != SYSTEM_UID
21140                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
21141                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
21142                Slog.w(TAG, "Skipping broadcast of " + intent
21143                        + ": user " + userId + " and its parent (if any) are stopped");
21144                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
21145            }
21146        }
21147
21148        final String action = intent.getAction();
21149        BroadcastOptions brOptions = null;
21150        if (bOptions != null) {
21151            brOptions = new BroadcastOptions(bOptions);
21152            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
21153                // See if the caller is allowed to do this.  Note we are checking against
21154                // the actual real caller (not whoever provided the operation as say a
21155                // PendingIntent), because that who is actually supplied the arguments.
21156                if (checkComponentPermission(
21157                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
21158                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
21159                        != PackageManager.PERMISSION_GRANTED) {
21160                    String msg = "Permission Denial: " + intent.getAction()
21161                            + " broadcast from " + callerPackage + " (pid=" + callingPid
21162                            + ", uid=" + callingUid + ")"
21163                            + " requires "
21164                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21165                    Slog.w(TAG, msg);
21166                    throw new SecurityException(msg);
21167                }
21168            }
21169            if (brOptions.isDontSendToRestrictedApps()
21170                    && !isUidActiveLocked(callingUid)
21171                    && isBackgroundRestrictedNoCheck(callingUid, callerPackage)) {
21172                Slog.i(TAG, "Not sending broadcast " + action + " - app " + callerPackage
21173                        + " has background restrictions");
21174                return ActivityManager.START_CANCELED;
21175            }
21176        }
21177
21178        // Verify that protected broadcasts are only being sent by system code,
21179        // and that system code is only sending protected broadcasts.
21180        final boolean isProtectedBroadcast;
21181        try {
21182            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
21183        } catch (RemoteException e) {
21184            Slog.w(TAG, "Remote exception", e);
21185            return ActivityManager.BROADCAST_SUCCESS;
21186        }
21187
21188        final boolean isCallerSystem;
21189        switch (UserHandle.getAppId(callingUid)) {
21190            case ROOT_UID:
21191            case SYSTEM_UID:
21192            case PHONE_UID:
21193            case BLUETOOTH_UID:
21194            case NFC_UID:
21195            case SE_UID:
21196                isCallerSystem = true;
21197                break;
21198            default:
21199                isCallerSystem = (callerApp != null) && callerApp.persistent;
21200                break;
21201        }
21202
21203        // First line security check before anything else: stop non-system apps from
21204        // sending protected broadcasts.
21205        if (!isCallerSystem) {
21206            if (isProtectedBroadcast) {
21207                String msg = "Permission Denial: not allowed to send broadcast "
21208                        + action + " from pid="
21209                        + callingPid + ", uid=" + callingUid;
21210                Slog.w(TAG, msg);
21211                throw new SecurityException(msg);
21212
21213            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
21214                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
21215                // Special case for compatibility: we don't want apps to send this,
21216                // but historically it has not been protected and apps may be using it
21217                // to poke their own app widget.  So, instead of making it protected,
21218                // just limit it to the caller.
21219                if (callerPackage == null) {
21220                    String msg = "Permission Denial: not allowed to send broadcast "
21221                            + action + " from unknown caller.";
21222                    Slog.w(TAG, msg);
21223                    throw new SecurityException(msg);
21224                } else if (intent.getComponent() != null) {
21225                    // They are good enough to send to an explicit component...  verify
21226                    // it is being sent to the calling app.
21227                    if (!intent.getComponent().getPackageName().equals(
21228                            callerPackage)) {
21229                        String msg = "Permission Denial: not allowed to send broadcast "
21230                                + action + " to "
21231                                + intent.getComponent().getPackageName() + " from "
21232                                + callerPackage;
21233                        Slog.w(TAG, msg);
21234                        throw new SecurityException(msg);
21235                    }
21236                } else {
21237                    // Limit broadcast to their own package.
21238                    intent.setPackage(callerPackage);
21239                }
21240            }
21241        }
21242
21243        if (action != null) {
21244            if (getBackgroundLaunchBroadcasts().contains(action)) {
21245                if (DEBUG_BACKGROUND_CHECK) {
21246                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
21247                }
21248                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
21249            }
21250
21251            switch (action) {
21252                case Intent.ACTION_UID_REMOVED:
21253                case Intent.ACTION_PACKAGE_REMOVED:
21254                case Intent.ACTION_PACKAGE_CHANGED:
21255                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21256                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21257                case Intent.ACTION_PACKAGES_SUSPENDED:
21258                case Intent.ACTION_PACKAGES_UNSUSPENDED:
21259                    // Handle special intents: if this broadcast is from the package
21260                    // manager about a package being removed, we need to remove all of
21261                    // its activities from the history stack.
21262                    if (checkComponentPermission(
21263                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
21264                            callingPid, callingUid, -1, true)
21265                            != PackageManager.PERMISSION_GRANTED) {
21266                        String msg = "Permission Denial: " + intent.getAction()
21267                                + " broadcast from " + callerPackage + " (pid=" + callingPid
21268                                + ", uid=" + callingUid + ")"
21269                                + " requires "
21270                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
21271                        Slog.w(TAG, msg);
21272                        throw new SecurityException(msg);
21273                    }
21274                    switch (action) {
21275                        case Intent.ACTION_UID_REMOVED:
21276                            final int uid = getUidFromIntent(intent);
21277                            if (uid >= 0) {
21278                                mBatteryStatsService.removeUid(uid);
21279                                mAppOpsService.uidRemoved(uid);
21280                            }
21281                            break;
21282                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21283                            // If resources are unavailable just force stop all those packages
21284                            // and flush the attribute cache as well.
21285                            String list[] =
21286                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21287                            if (list != null && list.length > 0) {
21288                                for (int i = 0; i < list.length; i++) {
21289                                    forceStopPackageLocked(list[i], -1, false, true, true,
21290                                            false, false, userId, "storage unmount");
21291                                }
21292                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21293                                sendPackageBroadcastLocked(
21294                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
21295                                        list, userId);
21296                            }
21297                            break;
21298                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21299                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21300                            break;
21301                        case Intent.ACTION_PACKAGE_REMOVED:
21302                        case Intent.ACTION_PACKAGE_CHANGED:
21303                            Uri data = intent.getData();
21304                            String ssp;
21305                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
21306                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
21307                                final boolean replacing =
21308                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21309                                final boolean killProcess =
21310                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
21311                                final boolean fullUninstall = removed && !replacing;
21312                                if (removed) {
21313                                    if (killProcess) {
21314                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
21315                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
21316                                                false, true, true, false, fullUninstall, userId,
21317                                                removed ? "pkg removed" : "pkg changed");
21318                                    }
21319                                    final int cmd = killProcess
21320                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
21321                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
21322                                    sendPackageBroadcastLocked(cmd,
21323                                            new String[] {ssp}, userId);
21324                                    if (fullUninstall) {
21325                                        mAppOpsService.packageRemoved(
21326                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
21327
21328                                        // Remove all permissions granted from/to this package
21329                                        removeUriPermissionsForPackageLocked(ssp, userId, true,
21330                                                false);
21331
21332                                        mRecentTasks.removeTasksByPackageName(ssp, userId);
21333
21334                                        mServices.forceStopPackageLocked(ssp, userId);
21335                                        mAppWarnings.onPackageUninstalled(ssp);
21336                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
21337                                        mBatteryStatsService.notePackageUninstalled(ssp);
21338                                    }
21339                                } else {
21340                                    if (killProcess) {
21341                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
21342                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
21343                                                userId, ProcessList.INVALID_ADJ,
21344                                                false, true, true, false, "change " + ssp);
21345                                    }
21346                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
21347                                            intent.getStringArrayExtra(
21348                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
21349                                }
21350                            }
21351                            break;
21352                        case Intent.ACTION_PACKAGES_SUSPENDED:
21353                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
21354                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
21355                                    intent.getAction());
21356                            final String[] packageNames = intent.getStringArrayExtra(
21357                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
21358                            final int userHandle = intent.getIntExtra(
21359                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
21360
21361                            synchronized(ActivityManagerService.this) {
21362                                mRecentTasks.onPackagesSuspendedChanged(
21363                                        packageNames, suspended, userHandle);
21364                            }
21365                            break;
21366                    }
21367                    break;
21368                case Intent.ACTION_PACKAGE_REPLACED:
21369                {
21370                    final Uri data = intent.getData();
21371                    final String ssp;
21372                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21373                        ApplicationInfo aInfo = null;
21374                        try {
21375                            aInfo = AppGlobals.getPackageManager()
21376                                    .getApplicationInfo(ssp, STOCK_PM_FLAGS, userId);
21377                        } catch (RemoteException ignore) {}
21378                        if (aInfo == null) {
21379                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
21380                                    + " ssp=" + ssp + " data=" + data);
21381                            return ActivityManager.BROADCAST_SUCCESS;
21382                        }
21383                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
21384                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
21385                                new String[] {ssp}, userId);
21386                    }
21387                    break;
21388                }
21389                case Intent.ACTION_PACKAGE_ADDED:
21390                {
21391                    // Special case for adding a package: by default turn on compatibility mode.
21392                    Uri data = intent.getData();
21393                    String ssp;
21394                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21395                        final boolean replacing =
21396                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21397                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
21398
21399                        try {
21400                            ApplicationInfo ai = AppGlobals.getPackageManager().
21401                                    getApplicationInfo(ssp, STOCK_PM_FLAGS, 0);
21402                            mBatteryStatsService.notePackageInstalled(ssp,
21403                                    ai != null ? ai.versionCode : 0);
21404                        } catch (RemoteException e) {
21405                        }
21406                    }
21407                    break;
21408                }
21409                case Intent.ACTION_PACKAGE_DATA_CLEARED:
21410                {
21411                    Uri data = intent.getData();
21412                    String ssp;
21413                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21414                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
21415                        mAppWarnings.onPackageDataCleared(ssp);
21416                    }
21417                    break;
21418                }
21419                case Intent.ACTION_TIMEZONE_CHANGED:
21420                    // If this is the time zone changed action, queue up a message that will reset
21421                    // the timezone of all currently running processes. This message will get
21422                    // queued up before the broadcast happens.
21423                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
21424                    break;
21425                case Intent.ACTION_TIME_CHANGED:
21426                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
21427                    // the tri-state value it may contain and "unknown".
21428                    // For convenience we re-use the Intent extra values.
21429                    final int NO_EXTRA_VALUE_FOUND = -1;
21430                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
21431                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
21432                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
21433                    // Only send a message if the time preference is available.
21434                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
21435                        Message updateTimePreferenceMsg =
21436                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
21437                                        timeFormatPreferenceMsgValue, 0);
21438                        mHandler.sendMessage(updateTimePreferenceMsg);
21439                    }
21440                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21441                    synchronized (stats) {
21442                        stats.noteCurrentTimeChangedLocked();
21443                    }
21444                    break;
21445                case Intent.ACTION_CLEAR_DNS_CACHE:
21446                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
21447                    break;
21448                case Proxy.PROXY_CHANGE_ACTION:
21449                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
21450                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
21451                    break;
21452                case android.hardware.Camera.ACTION_NEW_PICTURE:
21453                case android.hardware.Camera.ACTION_NEW_VIDEO:
21454                    // In N we just turned these off; in O we are turing them back on partly,
21455                    // only for registered receivers.  This will still address the main problem
21456                    // (a spam of apps waking up when a picture is taken putting significant
21457                    // memory pressure on the system at a bad point), while still allowing apps
21458                    // that are already actively running to know about this happening.
21459                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21460                    break;
21461                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
21462                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
21463                    break;
21464                case "com.android.launcher.action.INSTALL_SHORTCUT":
21465                    // As of O, we no longer support this broadcasts, even for pre-O apps.
21466                    // Apps should now be using ShortcutManager.pinRequestShortcut().
21467                    Log.w(TAG, "Broadcast " + action
21468                            + " no longer supported. It will not be delivered.");
21469                    return ActivityManager.BROADCAST_SUCCESS;
21470            }
21471
21472            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
21473                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
21474                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
21475                final int uid = getUidFromIntent(intent);
21476                if (uid != -1) {
21477                    final UidRecord uidRec = mActiveUids.get(uid);
21478                    if (uidRec != null) {
21479                        uidRec.updateHasInternetPermission();
21480                    }
21481                }
21482            }
21483        }
21484
21485        // Add to the sticky list if requested.
21486        if (sticky) {
21487            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
21488                    callingPid, callingUid)
21489                    != PackageManager.PERMISSION_GRANTED) {
21490                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
21491                        + callingPid + ", uid=" + callingUid
21492                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21493                Slog.w(TAG, msg);
21494                throw new SecurityException(msg);
21495            }
21496            if (requiredPermissions != null && requiredPermissions.length > 0) {
21497                Slog.w(TAG, "Can't broadcast sticky intent " + intent
21498                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
21499                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
21500            }
21501            if (intent.getComponent() != null) {
21502                throw new SecurityException(
21503                        "Sticky broadcasts can't target a specific component");
21504            }
21505            // We use userId directly here, since the "all" target is maintained
21506            // as a separate set of sticky broadcasts.
21507            if (userId != UserHandle.USER_ALL) {
21508                // But first, if this is not a broadcast to all users, then
21509                // make sure it doesn't conflict with an existing broadcast to
21510                // all users.
21511                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
21512                        UserHandle.USER_ALL);
21513                if (stickies != null) {
21514                    ArrayList<Intent> list = stickies.get(intent.getAction());
21515                    if (list != null) {
21516                        int N = list.size();
21517                        int i;
21518                        for (i=0; i<N; i++) {
21519                            if (intent.filterEquals(list.get(i))) {
21520                                throw new IllegalArgumentException(
21521                                        "Sticky broadcast " + intent + " for user "
21522                                        + userId + " conflicts with existing global broadcast");
21523                            }
21524                        }
21525                    }
21526                }
21527            }
21528            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21529            if (stickies == null) {
21530                stickies = new ArrayMap<>();
21531                mStickyBroadcasts.put(userId, stickies);
21532            }
21533            ArrayList<Intent> list = stickies.get(intent.getAction());
21534            if (list == null) {
21535                list = new ArrayList<>();
21536                stickies.put(intent.getAction(), list);
21537            }
21538            final int stickiesCount = list.size();
21539            int i;
21540            for (i = 0; i < stickiesCount; i++) {
21541                if (intent.filterEquals(list.get(i))) {
21542                    // This sticky already exists, replace it.
21543                    list.set(i, new Intent(intent));
21544                    break;
21545                }
21546            }
21547            if (i >= stickiesCount) {
21548                list.add(new Intent(intent));
21549            }
21550        }
21551
21552        int[] users;
21553        if (userId == UserHandle.USER_ALL) {
21554            // Caller wants broadcast to go to all started users.
21555            users = mUserController.getStartedUserArray();
21556        } else {
21557            // Caller wants broadcast to go to one specific user.
21558            users = new int[] {userId};
21559        }
21560
21561        // Figure out who all will receive this broadcast.
21562        List receivers = null;
21563        List<BroadcastFilter> registeredReceivers = null;
21564        // Need to resolve the intent to interested receivers...
21565        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
21566                 == 0) {
21567            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
21568        }
21569        if (intent.getComponent() == null) {
21570            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
21571                // Query one target user at a time, excluding shell-restricted users
21572                for (int i = 0; i < users.length; i++) {
21573                    if (mUserController.hasUserRestriction(
21574                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
21575                        continue;
21576                    }
21577                    List<BroadcastFilter> registeredReceiversForUser =
21578                            mReceiverResolver.queryIntent(intent,
21579                                    resolvedType, false /*defaultOnly*/, users[i]);
21580                    if (registeredReceivers == null) {
21581                        registeredReceivers = registeredReceiversForUser;
21582                    } else if (registeredReceiversForUser != null) {
21583                        registeredReceivers.addAll(registeredReceiversForUser);
21584                    }
21585                }
21586            } else {
21587                registeredReceivers = mReceiverResolver.queryIntent(intent,
21588                        resolvedType, false /*defaultOnly*/, userId);
21589            }
21590        }
21591
21592        final boolean replacePending =
21593                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
21594
21595        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
21596                + " replacePending=" + replacePending);
21597
21598        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
21599        if (!ordered && NR > 0) {
21600            // If we are not serializing this broadcast, then send the
21601            // registered receivers separately so they don't wait for the
21602            // components to be launched.
21603            if (isCallerSystem) {
21604                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21605                        isProtectedBroadcast, registeredReceivers);
21606            }
21607            final BroadcastQueue queue = broadcastQueueForIntent(intent);
21608            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21609                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21610                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
21611                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
21612            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
21613            final boolean replaced = replacePending
21614                    && (queue.replaceParallelBroadcastLocked(r) != null);
21615            // Note: We assume resultTo is null for non-ordered broadcasts.
21616            if (!replaced) {
21617                queue.enqueueParallelBroadcastLocked(r);
21618                queue.scheduleBroadcastsLocked();
21619            }
21620            registeredReceivers = null;
21621            NR = 0;
21622        }
21623
21624        // Merge into one list.
21625        int ir = 0;
21626        if (receivers != null) {
21627            // A special case for PACKAGE_ADDED: do not allow the package
21628            // being added to see this broadcast.  This prevents them from
21629            // using this as a back door to get run as soon as they are
21630            // installed.  Maybe in the future we want to have a special install
21631            // broadcast or such for apps, but we'd like to deliberately make
21632            // this decision.
21633            String skipPackages[] = null;
21634            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
21635                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
21636                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
21637                Uri data = intent.getData();
21638                if (data != null) {
21639                    String pkgName = data.getSchemeSpecificPart();
21640                    if (pkgName != null) {
21641                        skipPackages = new String[] { pkgName };
21642                    }
21643                }
21644            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
21645                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21646            }
21647            if (skipPackages != null && (skipPackages.length > 0)) {
21648                for (String skipPackage : skipPackages) {
21649                    if (skipPackage != null) {
21650                        int NT = receivers.size();
21651                        for (int it=0; it<NT; it++) {
21652                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
21653                            if (curt.activityInfo.packageName.equals(skipPackage)) {
21654                                receivers.remove(it);
21655                                it--;
21656                                NT--;
21657                            }
21658                        }
21659                    }
21660                }
21661            }
21662
21663            int NT = receivers != null ? receivers.size() : 0;
21664            int it = 0;
21665            ResolveInfo curt = null;
21666            BroadcastFilter curr = null;
21667            while (it < NT && ir < NR) {
21668                if (curt == null) {
21669                    curt = (ResolveInfo)receivers.get(it);
21670                }
21671                if (curr == null) {
21672                    curr = registeredReceivers.get(ir);
21673                }
21674                if (curr.getPriority() >= curt.priority) {
21675                    // Insert this broadcast record into the final list.
21676                    receivers.add(it, curr);
21677                    ir++;
21678                    curr = null;
21679                    it++;
21680                    NT++;
21681                } else {
21682                    // Skip to the next ResolveInfo in the final list.
21683                    it++;
21684                    curt = null;
21685                }
21686            }
21687        }
21688        while (ir < NR) {
21689            if (receivers == null) {
21690                receivers = new ArrayList();
21691            }
21692            receivers.add(registeredReceivers.get(ir));
21693            ir++;
21694        }
21695
21696        if (isCallerSystem) {
21697            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21698                    isProtectedBroadcast, receivers);
21699        }
21700
21701        if ((receivers != null && receivers.size() > 0)
21702                || resultTo != null) {
21703            BroadcastQueue queue = broadcastQueueForIntent(intent);
21704            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21705                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21706                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
21707                    resultData, resultExtras, ordered, sticky, false, userId);
21708
21709            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
21710                    + ": prev had " + queue.mOrderedBroadcasts.size());
21711            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
21712                    "Enqueueing broadcast " + r.intent.getAction());
21713
21714            final BroadcastRecord oldRecord =
21715                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
21716            if (oldRecord != null) {
21717                // Replaced, fire the result-to receiver.
21718                if (oldRecord.resultTo != null) {
21719                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
21720                    try {
21721                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
21722                                oldRecord.intent,
21723                                Activity.RESULT_CANCELED, null, null,
21724                                false, false, oldRecord.userId);
21725                    } catch (RemoteException e) {
21726                        Slog.w(TAG, "Failure ["
21727                                + queue.mQueueName + "] sending broadcast result of "
21728                                + intent, e);
21729
21730                    }
21731                }
21732            } else {
21733                queue.enqueueOrderedBroadcastLocked(r);
21734                queue.scheduleBroadcastsLocked();
21735            }
21736        } else {
21737            // There was nobody interested in the broadcast, but we still want to record
21738            // that it happened.
21739            if (intent.getComponent() == null && intent.getPackage() == null
21740                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21741                // This was an implicit broadcast... let's record it for posterity.
21742                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
21743            }
21744        }
21745
21746        return ActivityManager.BROADCAST_SUCCESS;
21747    }
21748
21749    /**
21750     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
21751     */
21752    private int getUidFromIntent(Intent intent) {
21753        if (intent == null) {
21754            return -1;
21755        }
21756        final Bundle intentExtras = intent.getExtras();
21757        return intent.hasExtra(Intent.EXTRA_UID)
21758                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
21759    }
21760
21761    final void rotateBroadcastStatsIfNeededLocked() {
21762        final long now = SystemClock.elapsedRealtime();
21763        if (mCurBroadcastStats == null ||
21764                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
21765            mLastBroadcastStats = mCurBroadcastStats;
21766            if (mLastBroadcastStats != null) {
21767                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
21768                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
21769            }
21770            mCurBroadcastStats = new BroadcastStats();
21771        }
21772    }
21773
21774    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
21775            int skipCount, long dispatchTime) {
21776        rotateBroadcastStatsIfNeededLocked();
21777        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
21778    }
21779
21780    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
21781        rotateBroadcastStatsIfNeededLocked();
21782        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
21783    }
21784
21785    final Intent verifyBroadcastLocked(Intent intent) {
21786        // Refuse possible leaked file descriptors
21787        if (intent != null && intent.hasFileDescriptors() == true) {
21788            throw new IllegalArgumentException("File descriptors passed in Intent");
21789        }
21790
21791        int flags = intent.getFlags();
21792
21793        if (!mProcessesReady) {
21794            // if the caller really truly claims to know what they're doing, go
21795            // ahead and allow the broadcast without launching any receivers
21796            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
21797                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
21798            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21799                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
21800                        + " before boot completion");
21801                throw new IllegalStateException("Cannot broadcast before boot completed");
21802            }
21803        }
21804
21805        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
21806            throw new IllegalArgumentException(
21807                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
21808        }
21809
21810        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21811            switch (Binder.getCallingUid()) {
21812                case ROOT_UID:
21813                case SHELL_UID:
21814                    break;
21815                default:
21816                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
21817                            + Binder.getCallingUid());
21818                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
21819                    break;
21820            }
21821        }
21822
21823        return intent;
21824    }
21825
21826    public final int broadcastIntent(IApplicationThread caller,
21827            Intent intent, String resolvedType, IIntentReceiver resultTo,
21828            int resultCode, String resultData, Bundle resultExtras,
21829            String[] requiredPermissions, int appOp, Bundle bOptions,
21830            boolean serialized, boolean sticky, int userId) {
21831        enforceNotIsolatedCaller("broadcastIntent");
21832        synchronized(this) {
21833            intent = verifyBroadcastLocked(intent);
21834
21835            final ProcessRecord callerApp = getRecordForAppLocked(caller);
21836            final int callingPid = Binder.getCallingPid();
21837            final int callingUid = Binder.getCallingUid();
21838            final long origId = Binder.clearCallingIdentity();
21839            int res = broadcastIntentLocked(callerApp,
21840                    callerApp != null ? callerApp.info.packageName : null,
21841                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
21842                    requiredPermissions, appOp, bOptions, serialized, sticky,
21843                    callingPid, callingUid, userId);
21844            Binder.restoreCallingIdentity(origId);
21845            return res;
21846        }
21847    }
21848
21849
21850    int broadcastIntentInPackage(String packageName, int uid,
21851            Intent intent, String resolvedType, IIntentReceiver resultTo,
21852            int resultCode, String resultData, Bundle resultExtras,
21853            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
21854            int userId) {
21855        synchronized(this) {
21856            intent = verifyBroadcastLocked(intent);
21857
21858            final long origId = Binder.clearCallingIdentity();
21859            String[] requiredPermissions = requiredPermission == null ? null
21860                    : new String[] {requiredPermission};
21861            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
21862                    resultTo, resultCode, resultData, resultExtras,
21863                    requiredPermissions, OP_NONE, bOptions, serialized,
21864                    sticky, -1, uid, userId);
21865            Binder.restoreCallingIdentity(origId);
21866            return res;
21867        }
21868    }
21869
21870    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
21871        // Refuse possible leaked file descriptors
21872        if (intent != null && intent.hasFileDescriptors() == true) {
21873            throw new IllegalArgumentException("File descriptors passed in Intent");
21874        }
21875
21876        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21877                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
21878
21879        synchronized(this) {
21880            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
21881                    != PackageManager.PERMISSION_GRANTED) {
21882                String msg = "Permission Denial: unbroadcastIntent() from pid="
21883                        + Binder.getCallingPid()
21884                        + ", uid=" + Binder.getCallingUid()
21885                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21886                Slog.w(TAG, msg);
21887                throw new SecurityException(msg);
21888            }
21889            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21890            if (stickies != null) {
21891                ArrayList<Intent> list = stickies.get(intent.getAction());
21892                if (list != null) {
21893                    int N = list.size();
21894                    int i;
21895                    for (i=0; i<N; i++) {
21896                        if (intent.filterEquals(list.get(i))) {
21897                            list.remove(i);
21898                            break;
21899                        }
21900                    }
21901                    if (list.size() <= 0) {
21902                        stickies.remove(intent.getAction());
21903                    }
21904                }
21905                if (stickies.size() <= 0) {
21906                    mStickyBroadcasts.remove(userId);
21907                }
21908            }
21909        }
21910    }
21911
21912    void backgroundServicesFinishedLocked(int userId) {
21913        for (BroadcastQueue queue : mBroadcastQueues) {
21914            queue.backgroundServicesFinishedLocked(userId);
21915        }
21916    }
21917
21918    public void finishReceiver(IBinder who, int resultCode, String resultData,
21919            Bundle resultExtras, boolean resultAbort, int flags) {
21920        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
21921
21922        // Refuse possible leaked file descriptors
21923        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
21924            throw new IllegalArgumentException("File descriptors passed in Bundle");
21925        }
21926
21927        final long origId = Binder.clearCallingIdentity();
21928        try {
21929            boolean doNext = false;
21930            BroadcastRecord r;
21931
21932            synchronized(this) {
21933                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
21934                        ? mFgBroadcastQueue : mBgBroadcastQueue;
21935                r = queue.getMatchingOrderedReceiver(who);
21936                if (r != null) {
21937                    doNext = r.queue.finishReceiverLocked(r, resultCode,
21938                        resultData, resultExtras, resultAbort, true);
21939                }
21940            }
21941
21942            if (doNext) {
21943                r.queue.processNextBroadcast(false);
21944            }
21945            trimApplications();
21946        } finally {
21947            Binder.restoreCallingIdentity(origId);
21948        }
21949    }
21950
21951    // =========================================================
21952    // INSTRUMENTATION
21953    // =========================================================
21954
21955    private static String[] HIDDENAPI_EXEMPT_PACKAGES = {
21956        "com.android.bluetooth.tests",
21957        "com.android.managedprovisioning.tests",
21958        "com.android.frameworks.coretests",
21959        "com.android.frameworks.coretests.binderproxycountingtestapp",
21960        "com.android.frameworks.coretests.binderproxycountingtestservice",
21961        "com.android.frameworks.tests.net",
21962        "com.android.frameworks.tests.uiservices",
21963        "com.android.coretests.apps.bstatstestapp",
21964        "com.android.servicestests.apps.conntestapp",
21965        "com.android.frameworks.servicestests",
21966        "com.android.frameworks.utiltests",
21967        "com.android.mtp.tests",
21968        "android.mtp",
21969        "com.android.documentsui.tests",
21970        "com.android.shell.tests",
21971        "com.android.systemui.tests",
21972        "com.android.testables",
21973        "android.net.wifi.test",
21974        "com.android.server.wifi.test",
21975        "com.android.frameworks.telephonytests",
21976        "com.android.providers.contacts.tests",
21977        "com.android.providers.contacts.tests2",
21978        "com.android.settings.tests.unit",
21979        "com.android.server.telecom.tests",
21980        "com.android.vcard.tests",
21981        "com.android.providers.blockednumber.tests",
21982        "android.settings.functional",
21983        "com.android.notification.functional",
21984        "com.android.frameworks.dexloggertest",
21985        "com.android.server.usb",
21986        "com.android.providers.downloads.tests",
21987        "com.android.emergency.tests.unit",
21988        "com.android.providers.calendar.tests",
21989        "com.android.settingslib",
21990        "com.android.rs.test",
21991        "com.android.printspooler.outofprocess.tests",
21992        "com.android.cellbroadcastreceiver.tests.unit",
21993        "com.android.providers.telephony.tests",
21994        "com.android.carrierconfig.tests",
21995        "com.android.phone.tests",
21996        "com.android.service.ims.presence.tests",
21997        "com.android.providers.setting.test",
21998        "com.android.frameworks.locationtests",
21999        "com.android.frameworks.coretests.privacy",
22000        "com.android.settings.ui",
22001    };
22002
22003    public boolean startInstrumentation(ComponentName className,
22004            String profileFile, int flags, Bundle arguments,
22005            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
22006            int userId, String abiOverride) {
22007        enforceNotIsolatedCaller("startInstrumentation");
22008        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22009                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
22010        // Refuse possible leaked file descriptors
22011        if (arguments != null && arguments.hasFileDescriptors()) {
22012            throw new IllegalArgumentException("File descriptors passed in Bundle");
22013        }
22014
22015        synchronized(this) {
22016            InstrumentationInfo ii = null;
22017            ApplicationInfo ai = null;
22018            try {
22019                ii = mContext.getPackageManager().getInstrumentationInfo(
22020                    className, STOCK_PM_FLAGS);
22021                ai = AppGlobals.getPackageManager().getApplicationInfo(
22022                        ii.targetPackage, STOCK_PM_FLAGS, userId);
22023            } catch (PackageManager.NameNotFoundException e) {
22024            } catch (RemoteException e) {
22025            }
22026            if (ii == null) {
22027                reportStartInstrumentationFailureLocked(watcher, className,
22028                        "Unable to find instrumentation info for: " + className);
22029                return false;
22030            }
22031            if (ai == null) {
22032                reportStartInstrumentationFailureLocked(watcher, className,
22033                        "Unable to find instrumentation target package: " + ii.targetPackage);
22034                return false;
22035            }
22036            if (!ai.hasCode()) {
22037                reportStartInstrumentationFailureLocked(watcher, className,
22038                        "Instrumentation target has no code: " + ii.targetPackage);
22039                return false;
22040            }
22041
22042            int match = mContext.getPackageManager().checkSignatures(
22043                    ii.targetPackage, ii.packageName);
22044            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
22045                String msg = "Permission Denial: starting instrumentation "
22046                        + className + " from pid="
22047                        + Binder.getCallingPid()
22048                        + ", uid=" + Binder.getCallingPid()
22049                        + " not allowed because package " + ii.packageName
22050                        + " does not have a signature matching the target "
22051                        + ii.targetPackage;
22052                reportStartInstrumentationFailureLocked(watcher, className, msg);
22053                throw new SecurityException(msg);
22054            }
22055
22056            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
22057            activeInstr.mClass = className;
22058            String defProcess = ai.processName;;
22059            if (ii.targetProcesses == null) {
22060                activeInstr.mTargetProcesses = new String[]{ai.processName};
22061            } else if (ii.targetProcesses.equals("*")) {
22062                activeInstr.mTargetProcesses = new String[0];
22063            } else {
22064                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
22065                defProcess = activeInstr.mTargetProcesses[0];
22066            }
22067            activeInstr.mTargetInfo = ai;
22068            activeInstr.mProfileFile = profileFile;
22069            activeInstr.mArguments = arguments;
22070            activeInstr.mWatcher = watcher;
22071            activeInstr.mUiAutomationConnection = uiAutomationConnection;
22072            activeInstr.mResultClass = className;
22073
22074            final long origId = Binder.clearCallingIdentity();
22075            // Instrumentation can kill and relaunch even persistent processes
22076            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
22077                    "start instr");
22078            // Inform usage stats to make the target package active
22079            if (mUsageStatsService != null) {
22080                mUsageStatsService.reportEvent(ii.targetPackage, userId,
22081                        UsageEvents.Event.SYSTEM_INTERACTION);
22082            }
22083            boolean disableHiddenApiChecks =
22084                    (flags & INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
22085
22086            // TODO: Temporary whitelist of packages which need to be exempt from hidden API
22087            //       checks. Remove this as soon as the testing infrastructure allows to set
22088            //       the flag in AndroidTest.xml.
22089            if (Arrays.asList(HIDDENAPI_EXEMPT_PACKAGES).contains(ai.packageName)) {
22090                disableHiddenApiChecks = true;
22091            }
22092
22093            ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
22094                    abiOverride);
22095            app.instr = activeInstr;
22096            activeInstr.mFinished = false;
22097            activeInstr.mRunningProcesses.add(app);
22098            if (!mActiveInstrumentation.contains(activeInstr)) {
22099                mActiveInstrumentation.add(activeInstr);
22100            }
22101            Binder.restoreCallingIdentity(origId);
22102        }
22103
22104        return true;
22105    }
22106
22107    /**
22108     * Report errors that occur while attempting to start Instrumentation.  Always writes the
22109     * error to the logs, but if somebody is watching, send the report there too.  This enables
22110     * the "am" command to report errors with more information.
22111     *
22112     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
22113     * @param cn The component name of the instrumentation.
22114     * @param report The error report.
22115     */
22116    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
22117            ComponentName cn, String report) {
22118        Slog.w(TAG, report);
22119        if (watcher != null) {
22120            Bundle results = new Bundle();
22121            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
22122            results.putString("Error", report);
22123            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
22124        }
22125    }
22126
22127    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
22128        if (app.instr == null) {
22129            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
22130            return;
22131        }
22132
22133        if (!app.instr.mFinished && results != null) {
22134            if (app.instr.mCurResults == null) {
22135                app.instr.mCurResults = new Bundle(results);
22136            } else {
22137                app.instr.mCurResults.putAll(results);
22138            }
22139        }
22140    }
22141
22142    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
22143        int userId = UserHandle.getCallingUserId();
22144        // Refuse possible leaked file descriptors
22145        if (results != null && results.hasFileDescriptors()) {
22146            throw new IllegalArgumentException("File descriptors passed in Intent");
22147        }
22148
22149        synchronized(this) {
22150            ProcessRecord app = getRecordForAppLocked(target);
22151            if (app == null) {
22152                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
22153                return;
22154            }
22155            final long origId = Binder.clearCallingIdentity();
22156            addInstrumentationResultsLocked(app, results);
22157            Binder.restoreCallingIdentity(origId);
22158        }
22159    }
22160
22161    @GuardedBy("this")
22162    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
22163        if (app.instr == null) {
22164            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
22165            return;
22166        }
22167
22168        if (!app.instr.mFinished) {
22169            if (app.instr.mWatcher != null) {
22170                Bundle finalResults = app.instr.mCurResults;
22171                if (finalResults != null) {
22172                    if (app.instr.mCurResults != null && results != null) {
22173                        finalResults.putAll(results);
22174                    }
22175                } else {
22176                    finalResults = results;
22177                }
22178                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
22179                        app.instr.mClass, resultCode, finalResults);
22180            }
22181
22182            // Can't call out of the system process with a lock held, so post a message.
22183            if (app.instr.mUiAutomationConnection != null) {
22184                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
22185                        app.instr.mUiAutomationConnection).sendToTarget();
22186            }
22187            app.instr.mFinished = true;
22188        }
22189
22190        app.instr.removeProcess(app);
22191        app.instr = null;
22192
22193        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
22194                "finished inst");
22195    }
22196
22197    public void finishInstrumentation(IApplicationThread target,
22198            int resultCode, Bundle results) {
22199        int userId = UserHandle.getCallingUserId();
22200        // Refuse possible leaked file descriptors
22201        if (results != null && results.hasFileDescriptors()) {
22202            throw new IllegalArgumentException("File descriptors passed in Intent");
22203        }
22204
22205        synchronized(this) {
22206            ProcessRecord app = getRecordForAppLocked(target);
22207            if (app == null) {
22208                Slog.w(TAG, "finishInstrumentation: no app for " + target);
22209                return;
22210            }
22211            final long origId = Binder.clearCallingIdentity();
22212            finishInstrumentationLocked(app, resultCode, results);
22213            Binder.restoreCallingIdentity(origId);
22214        }
22215    }
22216
22217    // =========================================================
22218    // CONFIGURATION
22219    // =========================================================
22220
22221    public ConfigurationInfo getDeviceConfigurationInfo() {
22222        ConfigurationInfo config = new ConfigurationInfo();
22223        synchronized (this) {
22224            final Configuration globalConfig = getGlobalConfiguration();
22225            config.reqTouchScreen = globalConfig.touchscreen;
22226            config.reqKeyboardType = globalConfig.keyboard;
22227            config.reqNavigation = globalConfig.navigation;
22228            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
22229                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
22230                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
22231            }
22232            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
22233                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
22234                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
22235            }
22236            config.reqGlEsVersion = GL_ES_VERSION;
22237        }
22238        return config;
22239    }
22240
22241    ActivityStack getFocusedStack() {
22242        return mStackSupervisor.getFocusedStack();
22243    }
22244
22245    @Override
22246    public StackInfo getFocusedStackInfo() throws RemoteException {
22247        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
22248        long ident = Binder.clearCallingIdentity();
22249        try {
22250            synchronized (this) {
22251                ActivityStack focusedStack = getFocusedStack();
22252                if (focusedStack != null) {
22253                    return mStackSupervisor.getStackInfo(focusedStack.mStackId);
22254                }
22255                return null;
22256            }
22257        } finally {
22258            Binder.restoreCallingIdentity(ident);
22259        }
22260    }
22261
22262    public Configuration getConfiguration() {
22263        Configuration ci;
22264        synchronized(this) {
22265            ci = new Configuration(getGlobalConfiguration());
22266            ci.userSetLocale = false;
22267        }
22268        return ci;
22269    }
22270
22271    @Override
22272    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
22273        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
22274        synchronized (this) {
22275            mSuppressResizeConfigChanges = suppress;
22276        }
22277    }
22278
22279    /**
22280     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
22281     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
22282     *       activity and clearing the task at the same time.
22283     */
22284    @Override
22285    // TODO: API should just be about changing windowing modes...
22286    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
22287        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
22288                "moveTasksToFullscreenStack()");
22289        synchronized (this) {
22290            final long origId = Binder.clearCallingIdentity();
22291            try {
22292                final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
22293                if (stack != null){
22294                    if (!stack.isActivityTypeStandardOrUndefined()) {
22295                        throw new IllegalArgumentException(
22296                                "You can't move tasks from non-standard stacks.");
22297                    }
22298                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
22299                }
22300            } finally {
22301                Binder.restoreCallingIdentity(origId);
22302            }
22303        }
22304    }
22305
22306    @Override
22307    public void updatePersistentConfiguration(Configuration values) {
22308        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
22309        enforceWriteSettingsPermission("updatePersistentConfiguration()");
22310        if (values == null) {
22311            throw new NullPointerException("Configuration must not be null");
22312        }
22313
22314        int userId = UserHandle.getCallingUserId();
22315
22316        synchronized(this) {
22317            updatePersistentConfigurationLocked(values, userId);
22318        }
22319    }
22320
22321    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
22322        final long origId = Binder.clearCallingIdentity();
22323        try {
22324            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
22325        } finally {
22326            Binder.restoreCallingIdentity(origId);
22327        }
22328    }
22329
22330    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
22331        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
22332                FONT_SCALE, 1.0f, userId);
22333
22334        synchronized (this) {
22335            if (getGlobalConfiguration().fontScale == scaleFactor) {
22336                return;
22337            }
22338
22339            final Configuration configuration
22340                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22341            configuration.fontScale = scaleFactor;
22342            updatePersistentConfigurationLocked(configuration, userId);
22343        }
22344    }
22345
22346    private void enforceWriteSettingsPermission(String func) {
22347        int uid = Binder.getCallingUid();
22348        if (uid == ROOT_UID) {
22349            return;
22350        }
22351
22352        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
22353                Settings.getPackageNameForUid(mContext, uid), false)) {
22354            return;
22355        }
22356
22357        String msg = "Permission Denial: " + func + " from pid="
22358                + Binder.getCallingPid()
22359                + ", uid=" + uid
22360                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
22361        Slog.w(TAG, msg);
22362        throw new SecurityException(msg);
22363    }
22364
22365    @Override
22366    public boolean updateConfiguration(Configuration values) {
22367        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
22368
22369        synchronized(this) {
22370            if (values == null && mWindowManager != null) {
22371                // sentinel: fetch the current configuration from the window manager
22372                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22373            }
22374
22375            if (mWindowManager != null) {
22376                // Update OOM levels based on display size.
22377                mProcessList.applyDisplaySize(mWindowManager);
22378            }
22379
22380            final long origId = Binder.clearCallingIdentity();
22381            try {
22382                if (values != null) {
22383                    Settings.System.clearConfiguration(values);
22384                }
22385                updateConfigurationLocked(values, null, false, false /* persistent */,
22386                        UserHandle.USER_NULL, false /* deferResume */,
22387                        mTmpUpdateConfigurationResult);
22388                return mTmpUpdateConfigurationResult.changes != 0;
22389            } finally {
22390                Binder.restoreCallingIdentity(origId);
22391            }
22392        }
22393    }
22394
22395    void updateUserConfigurationLocked() {
22396        final Configuration configuration = new Configuration(getGlobalConfiguration());
22397        final int currentUserId = mUserController.getCurrentUserId();
22398        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
22399                currentUserId, Settings.System.canWrite(mContext));
22400        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
22401                false /* persistent */, currentUserId, false /* deferResume */);
22402    }
22403
22404    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22405            boolean initLocale) {
22406        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
22407    }
22408
22409    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22410            boolean initLocale, boolean deferResume) {
22411        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
22412        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
22413                UserHandle.USER_NULL, deferResume);
22414    }
22415
22416    // To cache the list of supported system locales
22417    private String[] mSupportedSystemLocales = null;
22418
22419    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22420            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
22421        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
22422                deferResume, null /* result */);
22423    }
22424
22425    /**
22426     * Do either or both things: (1) change the current configuration, and (2)
22427     * make sure the given activity is running with the (now) current
22428     * configuration.  Returns true if the activity has been left running, or
22429     * false if <var>starting</var> is being destroyed to match the new
22430     * configuration.
22431     *
22432     * @param userId is only used when persistent parameter is set to true to persist configuration
22433     *               for that particular user
22434     */
22435    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22436            boolean initLocale, boolean persistent, int userId, boolean deferResume,
22437            UpdateConfigurationResult result) {
22438        int changes = 0;
22439        boolean kept = true;
22440
22441        if (mWindowManager != null) {
22442            mWindowManager.deferSurfaceLayout();
22443        }
22444        try {
22445            if (values != null) {
22446                changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
22447                        deferResume);
22448            }
22449
22450            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22451        } finally {
22452            if (mWindowManager != null) {
22453                mWindowManager.continueSurfaceLayout();
22454            }
22455        }
22456
22457        if (result != null) {
22458            result.changes = changes;
22459            result.activityRelaunched = !kept;
22460        }
22461        return kept;
22462    }
22463
22464    /**
22465     * Returns true if this configuration change is interesting enough to send an
22466     * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
22467     */
22468    private static boolean isSplitConfigurationChange(int configDiff) {
22469        return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
22470    }
22471
22472    /** Update default (global) configuration and notify listeners about changes. */
22473    private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
22474            boolean persistent, int userId, boolean deferResume) {
22475        mTempConfig.setTo(getGlobalConfiguration());
22476        final int changes = mTempConfig.updateFrom(values);
22477        if (changes == 0) {
22478            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
22479            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
22480            // performDisplayOverrideConfigUpdate in order to send the new display configuration
22481            // (even if there are no actual changes) to unfreeze the window.
22482            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
22483            return 0;
22484        }
22485
22486        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
22487                "Updating global configuration to: " + values);
22488
22489        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
22490        StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
22491                values.colorMode,
22492                values.densityDpi,
22493                values.fontScale,
22494                values.hardKeyboardHidden,
22495                values.keyboard,
22496                values.keyboardHidden,
22497                values.mcc,
22498                values.mnc,
22499                values.navigation,
22500                values.navigationHidden,
22501                values.orientation,
22502                values.screenHeightDp,
22503                values.screenLayout,
22504                values.screenWidthDp,
22505                values.smallestScreenWidthDp,
22506                values.touchscreen,
22507                values.uiMode);
22508
22509
22510        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
22511            final LocaleList locales = values.getLocales();
22512            int bestLocaleIndex = 0;
22513            if (locales.size() > 1) {
22514                if (mSupportedSystemLocales == null) {
22515                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
22516                }
22517                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
22518            }
22519            SystemProperties.set("persist.sys.locale",
22520                    locales.get(bestLocaleIndex).toLanguageTag());
22521            LocaleList.setDefault(locales, bestLocaleIndex);
22522            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
22523                    locales.get(bestLocaleIndex)));
22524        }
22525
22526        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
22527        mTempConfig.seq = mConfigurationSeq;
22528
22529        // Update stored global config and notify everyone about the change.
22530        mStackSupervisor.onConfigurationChanged(mTempConfig);
22531
22532        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
22533        // TODO(multi-display): Update UsageEvents#Event to include displayId.
22534        mUsageStatsService.reportConfigurationChange(mTempConfig,
22535                mUserController.getCurrentUserId());
22536
22537        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
22538        updateShouldShowDialogsLocked(mTempConfig);
22539
22540        AttributeCache ac = AttributeCache.instance();
22541        if (ac != null) {
22542            ac.updateConfiguration(mTempConfig);
22543        }
22544
22545        // Make sure all resources in our process are updated right now, so that anyone who is going
22546        // to retrieve resource values after we return will be sure to get the new ones. This is
22547        // especially important during boot, where the first config change needs to guarantee all
22548        // resources have that config before following boot code is executed.
22549        mSystemThread.applyConfigurationToResources(mTempConfig);
22550
22551        // We need another copy of global config because we're scheduling some calls instead of
22552        // running them in place. We need to be sure that object we send will be handled unchanged.
22553        final Configuration configCopy = new Configuration(mTempConfig);
22554        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
22555            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
22556            msg.obj = configCopy;
22557            msg.arg1 = userId;
22558            mHandler.sendMessage(msg);
22559        }
22560
22561        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22562            ProcessRecord app = mLruProcesses.get(i);
22563            try {
22564                if (app.thread != null) {
22565                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
22566                            + app.processName + " new config " + configCopy);
22567                    mLifecycleManager.scheduleTransaction(app.thread,
22568                            ConfigurationChangeItem.obtain(configCopy));
22569                }
22570            } catch (Exception e) {
22571                Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
22572            }
22573        }
22574
22575        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
22576        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
22577                | Intent.FLAG_RECEIVER_FOREGROUND
22578                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22579        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22580                OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22581                UserHandle.USER_ALL);
22582        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
22583            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
22584            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
22585                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
22586                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22587            if (initLocale || !mProcessesReady) {
22588                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
22589            }
22590            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22591                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22592                    UserHandle.USER_ALL);
22593        }
22594
22595        // Send a broadcast to PackageInstallers if the configuration change is interesting
22596        // for the purposes of installing additional splits.
22597        if (!initLocale && isSplitConfigurationChange(changes)) {
22598            intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
22599            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
22600                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
22601
22602            // Typically only app stores will have this permission.
22603            String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
22604            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
22605                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
22606        }
22607
22608        // Override configuration of the default display duplicates global config, so we need to
22609        // update it also. This will also notify WindowManager about changes.
22610        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
22611                DEFAULT_DISPLAY);
22612
22613        return changes;
22614    }
22615
22616    @Override
22617    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
22618        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
22619
22620        synchronized (this) {
22621            // Check if display is initialized in AM.
22622            if (!mStackSupervisor.isDisplayAdded(displayId)) {
22623                // Call might come when display is not yet added or has already been removed.
22624                if (DEBUG_CONFIGURATION) {
22625                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
22626                            + displayId);
22627                }
22628                return false;
22629            }
22630
22631            if (values == null && mWindowManager != null) {
22632                // sentinel: fetch the current configuration from the window manager
22633                values = mWindowManager.computeNewConfiguration(displayId);
22634            }
22635
22636            if (mWindowManager != null) {
22637                // Update OOM levels based on display size.
22638                mProcessList.applyDisplaySize(mWindowManager);
22639            }
22640
22641            final long origId = Binder.clearCallingIdentity();
22642            try {
22643                if (values != null) {
22644                    Settings.System.clearConfiguration(values);
22645                }
22646                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
22647                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
22648                return mTmpUpdateConfigurationResult.changes != 0;
22649            } finally {
22650                Binder.restoreCallingIdentity(origId);
22651            }
22652        }
22653    }
22654
22655    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
22656            boolean deferResume, int displayId) {
22657        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
22658                displayId, null /* result */);
22659    }
22660
22661    /**
22662     * Updates override configuration specific for the selected display. If no config is provided,
22663     * new one will be computed in WM based on current display info.
22664     */
22665    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
22666            ActivityRecord starting, boolean deferResume, int displayId,
22667            UpdateConfigurationResult result) {
22668        int changes = 0;
22669        boolean kept = true;
22670
22671        if (mWindowManager != null) {
22672            mWindowManager.deferSurfaceLayout();
22673        }
22674        try {
22675            if (values != null) {
22676                if (displayId == DEFAULT_DISPLAY) {
22677                    // Override configuration of the default display duplicates global config, so
22678                    // we're calling global config update instead for default display. It will also
22679                    // apply the correct override config.
22680                    changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
22681                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
22682                } else {
22683                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
22684                }
22685            }
22686
22687            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22688        } finally {
22689            if (mWindowManager != null) {
22690                mWindowManager.continueSurfaceLayout();
22691            }
22692        }
22693
22694        if (result != null) {
22695            result.changes = changes;
22696            result.activityRelaunched = !kept;
22697        }
22698        return kept;
22699    }
22700
22701    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
22702            int displayId) {
22703        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
22704        final int changes = mTempConfig.updateFrom(values);
22705        if (changes != 0) {
22706            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
22707                    + mTempConfig + " for displayId=" + displayId);
22708            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
22709
22710            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
22711            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
22712                mAppWarnings.onDensityChanged();
22713
22714                killAllBackgroundProcessesExcept(N,
22715                        ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
22716            }
22717        }
22718
22719        // Update the configuration with WM first and check if any of the stacks need to be resized
22720        // due to the configuration change. If so, resize the stacks now and do any relaunches if
22721        // necessary. This way we don't need to relaunch again afterwards in
22722        // ensureActivityConfiguration().
22723        if (mWindowManager != null) {
22724            final int[] resizedStacks =
22725                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
22726            if (resizedStacks != null) {
22727                for (int stackId : resizedStacks) {
22728                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
22729                }
22730            }
22731        }
22732
22733        return changes;
22734    }
22735
22736    /** Applies latest configuration and/or visibility updates if needed. */
22737    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
22738        boolean kept = true;
22739        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
22740        // mainStack is null during startup.
22741        if (mainStack != null) {
22742            if (changes != 0 && starting == null) {
22743                // If the configuration changed, and the caller is not already
22744                // in the process of starting an activity, then find the top
22745                // activity to check if its configuration needs to change.
22746                starting = mainStack.topRunningActivityLocked();
22747            }
22748
22749            if (starting != null) {
22750                kept = starting.ensureActivityConfiguration(changes,
22751                        false /* preserveWindow */);
22752                // And we need to make sure at this point that all other activities
22753                // are made visible with the correct configuration.
22754                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
22755                        !PRESERVE_WINDOWS);
22756            }
22757        }
22758
22759        return kept;
22760    }
22761
22762    /** Helper method that requests bounds from WM and applies them to stack. */
22763    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
22764        final Rect newStackBounds = new Rect();
22765        final ActivityStack stack = mStackSupervisor.getStack(stackId);
22766
22767        // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
22768        if (stack == null) {
22769            final StringWriter writer = new StringWriter();
22770            final PrintWriter printWriter = new PrintWriter(writer);
22771            mStackSupervisor.dumpDisplays(printWriter);
22772            printWriter.flush();
22773
22774            Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
22775        }
22776
22777        stack.getBoundsForNewConfiguration(newStackBounds);
22778        mStackSupervisor.resizeStackLocked(
22779                stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
22780                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
22781                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
22782    }
22783
22784    /**
22785     * Decide based on the configuration whether we should show the ANR,
22786     * crash, etc dialogs.  The idea is that if there is no affordance to
22787     * press the on-screen buttons, or the user experience would be more
22788     * greatly impacted than the crash itself, we shouldn't show the dialog.
22789     *
22790     * A thought: SystemUI might also want to get told about this, the Power
22791     * dialog / global actions also might want different behaviors.
22792     */
22793    private void updateShouldShowDialogsLocked(Configuration config) {
22794        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
22795                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
22796                                   && config.navigation == Configuration.NAVIGATION_NONAV);
22797        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
22798        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
22799                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
22800                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
22801                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
22802        final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
22803                HIDE_ERROR_DIALOGS, 0) != 0;
22804        mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
22805    }
22806
22807    @Override
22808    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
22809        synchronized (this) {
22810            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
22811            if (srec != null) {
22812                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
22813            }
22814        }
22815        return false;
22816    }
22817
22818    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
22819            Intent resultData) {
22820
22821        synchronized (this) {
22822            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
22823            if (r != null) {
22824                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
22825            }
22826            return false;
22827        }
22828    }
22829
22830    public int getLaunchedFromUid(IBinder activityToken) {
22831        ActivityRecord srec;
22832        synchronized (this) {
22833            srec = ActivityRecord.forTokenLocked(activityToken);
22834        }
22835        if (srec == null) {
22836            return -1;
22837        }
22838        return srec.launchedFromUid;
22839    }
22840
22841    public String getLaunchedFromPackage(IBinder activityToken) {
22842        ActivityRecord srec;
22843        synchronized (this) {
22844            srec = ActivityRecord.forTokenLocked(activityToken);
22845        }
22846        if (srec == null) {
22847            return null;
22848        }
22849        return srec.launchedFromPackage;
22850    }
22851
22852    // =========================================================
22853    // LIFETIME MANAGEMENT
22854    // =========================================================
22855
22856    // Returns whether the app is receiving broadcast.
22857    // If receiving, fetch all broadcast queues which the app is
22858    // the current [or imminent] receiver on.
22859    private boolean isReceivingBroadcastLocked(ProcessRecord app,
22860            ArraySet<BroadcastQueue> receivingQueues) {
22861        final int N = app.curReceivers.size();
22862        if (N > 0) {
22863            for (int i = 0; i < N; i++) {
22864                receivingQueues.add(app.curReceivers.valueAt(i).queue);
22865            }
22866            return true;
22867        }
22868
22869        // It's not the current receiver, but it might be starting up to become one
22870        for (BroadcastQueue queue : mBroadcastQueues) {
22871            final BroadcastRecord r = queue.mPendingBroadcast;
22872            if (r != null && r.curApp == app) {
22873                // found it; report which queue it's in
22874                receivingQueues.add(queue);
22875            }
22876        }
22877
22878        return !receivingQueues.isEmpty();
22879    }
22880
22881    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
22882            int targetUid, ComponentName targetComponent, String targetProcess) {
22883        if (!mTrackingAssociations) {
22884            return null;
22885        }
22886        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22887                = mAssociations.get(targetUid);
22888        if (components == null) {
22889            components = new ArrayMap<>();
22890            mAssociations.put(targetUid, components);
22891        }
22892        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22893        if (sourceUids == null) {
22894            sourceUids = new SparseArray<>();
22895            components.put(targetComponent, sourceUids);
22896        }
22897        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22898        if (sourceProcesses == null) {
22899            sourceProcesses = new ArrayMap<>();
22900            sourceUids.put(sourceUid, sourceProcesses);
22901        }
22902        Association ass = sourceProcesses.get(sourceProcess);
22903        if (ass == null) {
22904            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
22905                    targetProcess);
22906            sourceProcesses.put(sourceProcess, ass);
22907        }
22908        ass.mCount++;
22909        ass.mNesting++;
22910        if (ass.mNesting == 1) {
22911            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
22912            ass.mLastState = sourceState;
22913        }
22914        return ass;
22915    }
22916
22917    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
22918            ComponentName targetComponent) {
22919        if (!mTrackingAssociations) {
22920            return;
22921        }
22922        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22923                = mAssociations.get(targetUid);
22924        if (components == null) {
22925            return;
22926        }
22927        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22928        if (sourceUids == null) {
22929            return;
22930        }
22931        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22932        if (sourceProcesses == null) {
22933            return;
22934        }
22935        Association ass = sourceProcesses.get(sourceProcess);
22936        if (ass == null || ass.mNesting <= 0) {
22937            return;
22938        }
22939        ass.mNesting--;
22940        if (ass.mNesting == 0) {
22941            long uptime = SystemClock.uptimeMillis();
22942            ass.mTime += uptime - ass.mStartTime;
22943            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22944                    += uptime - ass.mLastStateUptime;
22945            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
22946        }
22947    }
22948
22949    private void noteUidProcessState(final int uid, final int state) {
22950        mBatteryStatsService.noteUidProcessState(uid, state);
22951        if (mTrackingAssociations) {
22952            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
22953                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
22954                        = mAssociations.valueAt(i1);
22955                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
22956                    SparseArray<ArrayMap<String, Association>> sourceUids
22957                            = targetComponents.valueAt(i2);
22958                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
22959                    if (sourceProcesses != null) {
22960                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
22961                            Association ass = sourceProcesses.valueAt(i4);
22962                            if (ass.mNesting >= 1) {
22963                                // currently associated
22964                                long uptime = SystemClock.uptimeMillis();
22965                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22966                                        += uptime - ass.mLastStateUptime;
22967                                ass.mLastState = state;
22968                                ass.mLastStateUptime = uptime;
22969                            }
22970                        }
22971                    }
22972                }
22973            }
22974        }
22975    }
22976
22977    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
22978            boolean doingAll, long now) {
22979        if (mAdjSeq == app.adjSeq) {
22980            // This adjustment has already been computed.
22981            return app.curRawAdj;
22982        }
22983
22984        if (app.thread == null) {
22985            app.adjSeq = mAdjSeq;
22986            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22987            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22988            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
22989        }
22990
22991        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
22992        app.adjSource = null;
22993        app.adjTarget = null;
22994        app.empty = false;
22995        app.cached = false;
22996
22997        final int activitiesSize = app.activities.size();
22998        final int appUid = app.info.uid;
22999        final int logUid = mCurOomAdjUid;
23000
23001        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
23002            // The max adjustment doesn't allow this app to be anything
23003            // below foreground, so it is not worth doing work for it.
23004            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23005                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making fixed: " + app);
23006            }
23007            app.adjType = "fixed";
23008            app.adjSeq = mAdjSeq;
23009            app.curRawAdj = app.maxAdj;
23010            app.foregroundActivities = false;
23011            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23012            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
23013            // System processes can do UI, and when they do we want to have
23014            // them trim their memory after the user leaves the UI.  To
23015            // facilitate this, here we need to determine whether or not it
23016            // is currently showing UI.
23017            app.systemNoUi = true;
23018            if (app == TOP_APP) {
23019                app.systemNoUi = false;
23020                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23021                app.adjType = "pers-top-activity";
23022            } else if (app.hasTopUi) {
23023                app.systemNoUi = false;
23024                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23025                app.adjType = "pers-top-ui";
23026            } else if (activitiesSize > 0) {
23027                for (int j = 0; j < activitiesSize; j++) {
23028                    final ActivityRecord r = app.activities.get(j);
23029                    if (r.visible) {
23030                        app.systemNoUi = false;
23031                    }
23032                }
23033            }
23034            if (!app.systemNoUi) {
23035                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
23036            }
23037            return (app.curAdj=app.maxAdj);
23038        }
23039
23040        app.systemNoUi = false;
23041
23042        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
23043
23044        // Determine the importance of the process, starting with most
23045        // important to least, and assign an appropriate OOM adjustment.
23046        int adj;
23047        int schedGroup;
23048        int procState;
23049        boolean foregroundActivities = false;
23050        mTmpBroadcastQueue.clear();
23051        if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
23052            // The last app on the list is the foreground app.
23053            adj = ProcessList.FOREGROUND_APP_ADJ;
23054            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23055            app.adjType = "top-activity";
23056            foregroundActivities = true;
23057            procState = PROCESS_STATE_CUR_TOP;
23058            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23059                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
23060            }
23061        } else if (app.runningRemoteAnimation) {
23062            adj = ProcessList.VISIBLE_APP_ADJ;
23063            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23064            app.adjType = "running-remote-anim";
23065            procState = PROCESS_STATE_CUR_TOP;
23066            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23067                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making running remote anim: " + app);
23068            }
23069        } else if (app.instr != null) {
23070            // Don't want to kill running instrumentation.
23071            adj = ProcessList.FOREGROUND_APP_ADJ;
23072            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23073            app.adjType = "instrumentation";
23074            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
23075            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23076                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app);
23077            }
23078        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
23079            // An app that is currently receiving a broadcast also
23080            // counts as being in the foreground for OOM killer purposes.
23081            // It's placed in a sched group based on the nature of the
23082            // broadcast as reflected by which queue it's active in.
23083            adj = ProcessList.FOREGROUND_APP_ADJ;
23084            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
23085                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
23086            app.adjType = "broadcast";
23087            procState = ActivityManager.PROCESS_STATE_RECEIVER;
23088            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23089                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making broadcast: " + app);
23090            }
23091        } else if (app.executingServices.size() > 0) {
23092            // An app that is currently executing a service callback also
23093            // counts as being in the foreground.
23094            adj = ProcessList.FOREGROUND_APP_ADJ;
23095            schedGroup = app.execServicesFg ?
23096                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
23097            app.adjType = "exec-service";
23098            procState = ActivityManager.PROCESS_STATE_SERVICE;
23099            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23100                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app);
23101            }
23102            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
23103        } else if (app == TOP_APP) {
23104            adj = ProcessList.FOREGROUND_APP_ADJ;
23105            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23106            app.adjType = "top-sleeping";
23107            foregroundActivities = true;
23108            procState = PROCESS_STATE_CUR_TOP;
23109            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23110                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top (sleeping): " + app);
23111            }
23112        } else {
23113            // As far as we know the process is empty.  We may change our mind later.
23114            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23115            // At this point we don't actually know the adjustment.  Use the cached adj
23116            // value that the caller wants us to.
23117            adj = cachedAdj;
23118            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23119            app.cached = true;
23120            app.empty = true;
23121            app.adjType = "cch-empty";
23122            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23123                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making empty: " + app);
23124            }
23125        }
23126
23127        // Examine all activities if not already foreground.
23128        if (!foregroundActivities && activitiesSize > 0) {
23129            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
23130            for (int j = 0; j < activitiesSize; j++) {
23131                final ActivityRecord r = app.activities.get(j);
23132                if (r.app != app) {
23133                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
23134                            + " instead of expected " + app);
23135                    if (r.app == null || (r.app.uid == app.uid)) {
23136                        // Only fix things up when they look sane
23137                        r.setProcess(app);
23138                    } else {
23139                        continue;
23140                    }
23141                }
23142                if (r.visible) {
23143                    // App has a visible activity; only upgrade adjustment.
23144                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
23145                        adj = ProcessList.VISIBLE_APP_ADJ;
23146                        app.adjType = "vis-activity";
23147                        if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23148                            reportOomAdjMessageLocked(TAG_OOM_ADJ,
23149                                    "Raise adj to vis-activity: " + app);
23150                        }
23151                    }
23152                    if (procState > PROCESS_STATE_CUR_TOP) {
23153                        procState = PROCESS_STATE_CUR_TOP;
23154                        app.adjType = "vis-activity";
23155                        if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23156                            reportOomAdjMessageLocked(TAG_OOM_ADJ,
23157                                    "Raise procstate to vis-activity (top): " + app);
23158                        }
23159                    }
23160                    if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
23161                        schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23162                    }
23163                    app.cached = false;
23164                    app.empty = false;
23165                    foregroundActivities = true;
23166                    final TaskRecord task = r.getTask();
23167                    if (task != null && minLayer > 0) {
23168                        final int layer = task.mLayerRank;
23169                        if (layer >= 0 && minLayer > layer) {
23170                            minLayer = layer;
23171                        }
23172                    }
23173                    break;
23174                } else if (r.isState(ActivityState.PAUSING, ActivityState.PAUSED)) {
23175                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23176                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23177                        app.adjType = "pause-activity";
23178                        if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23179                            reportOomAdjMessageLocked(TAG_OOM_ADJ,
23180                                    "Raise adj to pause-activity: "  + app);
23181                        }
23182                    }
23183                    if (procState > PROCESS_STATE_CUR_TOP) {
23184                        procState = PROCESS_STATE_CUR_TOP;
23185                        app.adjType = "pause-activity";
23186                        if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23187                            reportOomAdjMessageLocked(TAG_OOM_ADJ,
23188                                    "Raise procstate to pause-activity (top): "  + app);
23189                        }
23190                    }
23191                    if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
23192                        schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23193                    }
23194                    app.cached = false;
23195                    app.empty = false;
23196                    foregroundActivities = true;
23197                } else if (r.isState(ActivityState.STOPPING)) {
23198                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23199                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23200                        app.adjType = "stop-activity";
23201                        if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23202                            reportOomAdjMessageLocked(TAG_OOM_ADJ,
23203                                    "Raise adj to stop-activity: "  + app);
23204                        }
23205                    }
23206                    // For the process state, we will at this point consider the
23207                    // process to be cached.  It will be cached either as an activity
23208                    // or empty depending on whether the activity is finishing.  We do
23209                    // this so that we can treat the process as cached for purposes of
23210                    // memory trimming (determing current memory level, trim command to
23211                    // send to process) since there can be an arbitrary number of stopping
23212                    // processes and they should soon all go into the cached state.
23213                    if (!r.finishing) {
23214                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23215                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23216                            app.adjType = "stop-activity";
23217                            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23218                                reportOomAdjMessageLocked(TAG_OOM_ADJ,
23219                                        "Raise procstate to stop-activity: " + app);
23220                            }
23221                        }
23222                    }
23223                    app.cached = false;
23224                    app.empty = false;
23225                    foregroundActivities = true;
23226                } else {
23227                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23228                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
23229                        app.adjType = "cch-act";
23230                        if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23231                            reportOomAdjMessageLocked(TAG_OOM_ADJ,
23232                                    "Raise procstate to cached activity: " + app);
23233                        }
23234                    }
23235                }
23236            }
23237            if (adj == ProcessList.VISIBLE_APP_ADJ) {
23238                adj += minLayer;
23239            }
23240        }
23241        if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) {
23242            procState = ActivityManager.PROCESS_STATE_CACHED_RECENT;
23243            app.adjType = "cch-rec";
23244            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23245                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to cached recent: " + app);
23246            }
23247        }
23248
23249        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
23250                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
23251            if (app.foregroundServices) {
23252                // The user is aware of this app, so make it visible.
23253                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23254                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
23255                app.cached = false;
23256                app.adjType = "fg-service";
23257                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23258                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23259                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to fg service: " + app);
23260                }
23261            } else if (app.hasOverlayUi) {
23262                // The process is display an overlay UI.
23263                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23264                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23265                app.cached = false;
23266                app.adjType = "has-overlay-ui";
23267                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23268                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23269                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to overlay ui: " + app);
23270                }
23271            }
23272        }
23273
23274        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
23275                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23276            if (app.forcingToImportant != null) {
23277                // This is currently used for toasts...  they are not interactive, and
23278                // we don't want them to cause the app to become fully foreground (and
23279                // thus out of background check), so we yes the best background level we can.
23280                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23281                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23282                app.cached = false;
23283                app.adjType = "force-imp";
23284                app.adjSource = app.forcingToImportant;
23285                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23286                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23287                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to force imp: " + app);
23288                }
23289            }
23290        }
23291
23292        if (app == mHeavyWeightProcess) {
23293            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
23294                // We don't want to kill the current heavy-weight process.
23295                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
23296                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23297                app.cached = false;
23298                app.adjType = "heavy";
23299                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23300                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to heavy: " + app);
23301                }
23302            }
23303            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
23304                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
23305                app.adjType = "heavy";
23306                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23307                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to heavy: " + app);
23308                }
23309            }
23310        }
23311
23312        if (app == mHomeProcess) {
23313            if (adj > ProcessList.HOME_APP_ADJ) {
23314                // This process is hosting what we currently consider to be the
23315                // home app, so we don't want to let it go into the background.
23316                adj = ProcessList.HOME_APP_ADJ;
23317                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23318                app.cached = false;
23319                app.adjType = "home";
23320                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23321                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to home: " + app);
23322                }
23323            }
23324            if (procState > ActivityManager.PROCESS_STATE_HOME) {
23325                procState = ActivityManager.PROCESS_STATE_HOME;
23326                app.adjType = "home";
23327                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23328                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to home: " + app);
23329                }
23330            }
23331        }
23332
23333        if (app == mPreviousProcess && app.activities.size() > 0) {
23334            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23335                // This was the previous process that showed UI to the user.
23336                // We want to try to keep it around more aggressively, to give
23337                // a good experience around switching between two apps.
23338                adj = ProcessList.PREVIOUS_APP_ADJ;
23339                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23340                app.cached = false;
23341                app.adjType = "previous";
23342                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23343                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to prev: " + app);
23344                }
23345            }
23346            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23347                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23348                app.adjType = "previous";
23349                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23350                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to prev: " + app);
23351                }
23352            }
23353        }
23354
23355        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
23356                + " reason=" + app.adjType);
23357
23358        // By default, we use the computed adjustment.  It may be changed if
23359        // there are applications dependent on our services or providers, but
23360        // this gives us a baseline and makes sure we don't get into an
23361        // infinite recursion.
23362        app.adjSeq = mAdjSeq;
23363        app.curRawAdj = adj;
23364        app.hasStartedServices = false;
23365
23366        if (mBackupTarget != null && app == mBackupTarget.app) {
23367            // If possible we want to avoid killing apps while they're being backed up
23368            if (adj > ProcessList.BACKUP_APP_ADJ) {
23369                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
23370                adj = ProcessList.BACKUP_APP_ADJ;
23371                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23372                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23373                }
23374                app.adjType = "backup";
23375                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23376                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to backup: " + app);
23377                }
23378                app.cached = false;
23379            }
23380            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
23381                procState = ActivityManager.PROCESS_STATE_BACKUP;
23382                app.adjType = "backup";
23383                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23384                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to backup: " + app);
23385                }
23386            }
23387        }
23388
23389        boolean mayBeTop = false;
23390        String mayBeTopType = null;
23391        Object mayBeTopSource = null;
23392        Object mayBeTopTarget = null;
23393
23394        for (int is = app.services.size()-1;
23395                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23396                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23397                        || procState > ActivityManager.PROCESS_STATE_TOP);
23398                is--) {
23399            ServiceRecord s = app.services.valueAt(is);
23400            if (s.startRequested) {
23401                app.hasStartedServices = true;
23402                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
23403                    procState = ActivityManager.PROCESS_STATE_SERVICE;
23404                    app.adjType = "started-services";
23405                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23406                        reportOomAdjMessageLocked(TAG_OOM_ADJ,
23407                                "Raise procstate to started service: " + app);
23408                    }
23409                }
23410                if (app.hasShownUi && app != mHomeProcess) {
23411                    // If this process has shown some UI, let it immediately
23412                    // go to the LRU list because it may be pretty heavy with
23413                    // UI stuff.  We'll tag it with a label just to help
23414                    // debug and understand what is going on.
23415                    if (adj > ProcessList.SERVICE_ADJ) {
23416                        app.adjType = "cch-started-ui-services";
23417                    }
23418                } else {
23419                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23420                        // This service has seen some activity within
23421                        // recent memory, so we will keep its process ahead
23422                        // of the background processes.
23423                        if (adj > ProcessList.SERVICE_ADJ) {
23424                            adj = ProcessList.SERVICE_ADJ;
23425                            app.adjType = "started-services";
23426                            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23427                                reportOomAdjMessageLocked(TAG_OOM_ADJ,
23428                                        "Raise adj to started service: " + app);
23429                            }
23430                            app.cached = false;
23431                        }
23432                    }
23433                    // If we have let the service slide into the background
23434                    // state, still have some text describing what it is doing
23435                    // even though the service no longer has an impact.
23436                    if (adj > ProcessList.SERVICE_ADJ) {
23437                        app.adjType = "cch-started-services";
23438                    }
23439                }
23440            }
23441
23442            for (int conni = s.connections.size()-1;
23443                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23444                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23445                            || procState > ActivityManager.PROCESS_STATE_TOP);
23446                    conni--) {
23447                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
23448                for (int i = 0;
23449                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
23450                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23451                                || procState > ActivityManager.PROCESS_STATE_TOP);
23452                        i++) {
23453                    // XXX should compute this based on the max of
23454                    // all connected clients.
23455                    ConnectionRecord cr = clist.get(i);
23456                    if (cr.binding.client == app) {
23457                        // Binding to ourself is not interesting.
23458                        continue;
23459                    }
23460
23461                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
23462                        ProcessRecord client = cr.binding.client;
23463                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
23464                                TOP_APP, doingAll, now);
23465                        int clientProcState = client.curProcState;
23466                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23467                            // If the other app is cached for any reason, for purposes here
23468                            // we are going to consider it empty.  The specific cached state
23469                            // doesn't propagate except under certain conditions.
23470                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23471                        }
23472                        String adjType = null;
23473                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
23474                            // Not doing bind OOM management, so treat
23475                            // this guy more like a started service.
23476                            if (app.hasShownUi && app != mHomeProcess) {
23477                                // If this process has shown some UI, let it immediately
23478                                // go to the LRU list because it may be pretty heavy with
23479                                // UI stuff.  We'll tag it with a label just to help
23480                                // debug and understand what is going on.
23481                                if (adj > clientAdj) {
23482                                    adjType = "cch-bound-ui-services";
23483                                }
23484                                app.cached = false;
23485                                clientAdj = adj;
23486                                clientProcState = procState;
23487                            } else {
23488                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23489                                    // This service has not seen activity within
23490                                    // recent memory, so allow it to drop to the
23491                                    // LRU list if there is no other reason to keep
23492                                    // it around.  We'll also tag it with a label just
23493                                    // to help debug and undertand what is going on.
23494                                    if (adj > clientAdj) {
23495                                        adjType = "cch-bound-services";
23496                                    }
23497                                    clientAdj = adj;
23498                                }
23499                            }
23500                        }
23501                        if (adj > clientAdj) {
23502                            // If this process has recently shown UI, and
23503                            // the process that is binding to it is less
23504                            // important than being visible, then we don't
23505                            // care about the binding as much as we care
23506                            // about letting this process get into the LRU
23507                            // list to be killed and restarted if needed for
23508                            // memory.
23509                            if (app.hasShownUi && app != mHomeProcess
23510                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23511                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
23512                                    adjType = "cch-bound-ui-services";
23513                                }
23514                            } else {
23515                                int newAdj;
23516                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
23517                                        |Context.BIND_IMPORTANT)) != 0) {
23518                                    newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
23519                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
23520                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
23521                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
23522                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23523                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
23524                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
23525                                    newAdj = clientAdj;
23526                                } else {
23527                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
23528                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
23529                                    } else {
23530                                        newAdj = adj;
23531                                    }
23532                                }
23533                                if (!client.cached) {
23534                                    app.cached = false;
23535                                }
23536                                if (adj >  newAdj) {
23537                                    adj = newAdj;
23538                                    adjType = "service";
23539                                }
23540                            }
23541                        }
23542                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
23543                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
23544                            // This will treat important bound services identically to
23545                            // the top app, which may behave differently than generic
23546                            // foreground work.
23547                            if (client.curSchedGroup > schedGroup) {
23548                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23549                                    schedGroup = client.curSchedGroup;
23550                                } else {
23551                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23552                                }
23553                            }
23554                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23555                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23556                                    // Special handling of clients who are in the top state.
23557                                    // We *may* want to consider this process to be in the
23558                                    // top state as well, but only if there is not another
23559                                    // reason for it to be running.  Being on the top is a
23560                                    // special state, meaning you are specifically running
23561                                    // for the current top app.  If the process is already
23562                                    // running in the background for some other reason, it
23563                                    // is more important to continue considering it to be
23564                                    // in the background state.
23565                                    mayBeTop = true;
23566                                    mayBeTopType = "service";
23567                                    mayBeTopSource = cr.binding.client;
23568                                    mayBeTopTarget = s.name;
23569                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23570                                } else {
23571                                    // Special handling for above-top states (persistent
23572                                    // processes).  These should not bring the current process
23573                                    // into the top state, since they are not on top.  Instead
23574                                    // give them the best state after that.
23575                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
23576                                        clientProcState =
23577                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23578                                    } else if (mWakefulness
23579                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
23580                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
23581                                                    != 0) {
23582                                        clientProcState =
23583                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23584                                    } else {
23585                                        clientProcState =
23586                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23587                                    }
23588                                }
23589                            }
23590                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
23591                            if (clientProcState <
23592                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23593                                clientProcState =
23594                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23595                            }
23596                        } else {
23597                            if (clientProcState <
23598                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
23599                                clientProcState =
23600                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
23601                            }
23602                        }
23603                        if (procState > clientProcState) {
23604                            procState = clientProcState;
23605                            if (adjType == null) {
23606                                adjType = "service";
23607                            }
23608                        }
23609                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
23610                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
23611                            app.pendingUiClean = true;
23612                        }
23613                        if (adjType != null) {
23614                            app.adjType = adjType;
23615                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23616                                    .REASON_SERVICE_IN_USE;
23617                            app.adjSource = cr.binding.client;
23618                            app.adjSourceProcState = clientProcState;
23619                            app.adjTarget = s.name;
23620                            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23621                                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
23622                                        + ": " + app + ", due to " + cr.binding.client
23623                                        + " adj=" + adj + " procState="
23624                                        + ProcessList.makeProcStateString(procState));
23625                            }
23626                        }
23627                    }
23628                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
23629                        app.treatLikeActivity = true;
23630                    }
23631                    final ActivityRecord a = cr.activity;
23632                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
23633                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && (a.visible
23634                                || a.isState(ActivityState.RESUMED, ActivityState.PAUSING))) {
23635                            adj = ProcessList.FOREGROUND_APP_ADJ;
23636                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
23637                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23638                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
23639                                } else {
23640                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23641                                }
23642                            }
23643                            app.cached = false;
23644                            app.adjType = "service";
23645                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23646                                    .REASON_SERVICE_IN_USE;
23647                            app.adjSource = a;
23648                            app.adjSourceProcState = procState;
23649                            app.adjTarget = s.name;
23650                            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23651                                reportOomAdjMessageLocked(TAG_OOM_ADJ,
23652                                        "Raise to service w/activity: " + app);
23653                            }
23654                        }
23655                    }
23656                }
23657            }
23658        }
23659
23660        for (int provi = app.pubProviders.size()-1;
23661                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23662                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23663                        || procState > ActivityManager.PROCESS_STATE_TOP);
23664                provi--) {
23665            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
23666            for (int i = cpr.connections.size()-1;
23667                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23668                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23669                            || procState > ActivityManager.PROCESS_STATE_TOP);
23670                    i--) {
23671                ContentProviderConnection conn = cpr.connections.get(i);
23672                ProcessRecord client = conn.client;
23673                if (client == app) {
23674                    // Being our own client is not interesting.
23675                    continue;
23676                }
23677                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
23678                int clientProcState = client.curProcState;
23679                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23680                    // If the other app is cached for any reason, for purposes here
23681                    // we are going to consider it empty.
23682                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23683                }
23684                String adjType = null;
23685                if (adj > clientAdj) {
23686                    if (app.hasShownUi && app != mHomeProcess
23687                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23688                        adjType = "cch-ui-provider";
23689                    } else {
23690                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
23691                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
23692                        adjType = "provider";
23693                    }
23694                    app.cached &= client.cached;
23695                }
23696                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23697                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23698                        // Special handling of clients who are in the top state.
23699                        // We *may* want to consider this process to be in the
23700                        // top state as well, but only if there is not another
23701                        // reason for it to be running.  Being on the top is a
23702                        // special state, meaning you are specifically running
23703                        // for the current top app.  If the process is already
23704                        // running in the background for some other reason, it
23705                        // is more important to continue considering it to be
23706                        // in the background state.
23707                        mayBeTop = true;
23708                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23709                        mayBeTopType = adjType = "provider-top";
23710                        mayBeTopSource = client;
23711                        mayBeTopTarget = cpr.name;
23712                    } else {
23713                        // Special handling for above-top states (persistent
23714                        // processes).  These should not bring the current process
23715                        // into the top state, since they are not on top.  Instead
23716                        // give them the best state after that.
23717                        clientProcState =
23718                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23719                        if (adjType == null) {
23720                            adjType = "provider";
23721                        }
23722                    }
23723                }
23724                if (procState > clientProcState) {
23725                    procState = clientProcState;
23726                }
23727                if (client.curSchedGroup > schedGroup) {
23728                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23729                }
23730                if (adjType != null) {
23731                    app.adjType = adjType;
23732                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23733                            .REASON_PROVIDER_IN_USE;
23734                    app.adjSource = client;
23735                    app.adjSourceProcState = clientProcState;
23736                    app.adjTarget = cpr.name;
23737                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23738                        reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
23739                                + ": " + app + ", due to " + client
23740                                + " adj=" + adj + " procState="
23741                                + ProcessList.makeProcStateString(procState));
23742                    }
23743                }
23744            }
23745            // If the provider has external (non-framework) process
23746            // dependencies, ensure that its adjustment is at least
23747            // FOREGROUND_APP_ADJ.
23748            if (cpr.hasExternalProcessHandles()) {
23749                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
23750                    adj = ProcessList.FOREGROUND_APP_ADJ;
23751                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23752                    app.cached = false;
23753                    app.adjType = "ext-provider";
23754                    app.adjTarget = cpr.name;
23755                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23756                        reportOomAdjMessageLocked(TAG_OOM_ADJ,
23757                                "Raise adj to external provider: " + app);
23758                    }
23759                }
23760                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23761                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23762                    reportOomAdjMessageLocked(TAG_OOM_ADJ,
23763                            "Raise procstate to external provider: " + app);
23764                }
23765            }
23766        }
23767
23768        if (app.lastProviderTime > 0 &&
23769                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
23770            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23771                adj = ProcessList.PREVIOUS_APP_ADJ;
23772                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23773                app.cached = false;
23774                app.adjType = "recent-provider";
23775                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23776                    reportOomAdjMessageLocked(TAG_OOM_ADJ,
23777                            "Raise adj to recent provider: " + app);
23778                }
23779            }
23780            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23781                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23782                app.adjType = "recent-provider";
23783                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23784                    reportOomAdjMessageLocked(TAG_OOM_ADJ,
23785                            "Raise procstate to recent provider: " + app);
23786                }
23787            }
23788        }
23789
23790        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
23791            // A client of one of our services or providers is in the top state.  We
23792            // *may* want to be in the top state, but not if we are already running in
23793            // the background for some other reason.  For the decision here, we are going
23794            // to pick out a few specific states that we want to remain in when a client
23795            // is top (states that tend to be longer-term) and otherwise allow it to go
23796            // to the top state.
23797            switch (procState) {
23798                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
23799                case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
23800                    // Something else is keeping it at this level, just leave it.
23801                    break;
23802                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
23803                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
23804                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
23805                case ActivityManager.PROCESS_STATE_SERVICE:
23806                    // These all are longer-term states, so pull them up to the top
23807                    // of the background states, but not all the way to the top state.
23808                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23809                    app.adjType = mayBeTopType;
23810                    app.adjSource = mayBeTopSource;
23811                    app.adjTarget = mayBeTopTarget;
23812                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23813                        reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
23814                                + ": " + app + ", due to " + mayBeTopSource
23815                                + " adj=" + adj + " procState="
23816                                + ProcessList.makeProcStateString(procState));
23817                    }
23818                    break;
23819                default:
23820                    // Otherwise, top is a better choice, so take it.
23821                    procState = ActivityManager.PROCESS_STATE_TOP;
23822                    app.adjType = mayBeTopType;
23823                    app.adjSource = mayBeTopSource;
23824                    app.adjTarget = mayBeTopTarget;
23825                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23826                        reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
23827                                + ": " + app + ", due to " + mayBeTopSource
23828                                + " adj=" + adj + " procState="
23829                                + ProcessList.makeProcStateString(procState));
23830                    }
23831                    break;
23832            }
23833        }
23834
23835        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
23836            if (app.hasClientActivities) {
23837                // This is a cached process, but with client activities.  Mark it so.
23838                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
23839                app.adjType = "cch-client-act";
23840            } else if (app.treatLikeActivity) {
23841                // This is a cached process, but somebody wants us to treat it like it has
23842                // an activity, okay!
23843                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
23844                app.adjType = "cch-as-act";
23845            }
23846        }
23847
23848        if (adj == ProcessList.SERVICE_ADJ) {
23849            if (doingAll) {
23850                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
23851                mNewNumServiceProcs++;
23852                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
23853                if (!app.serviceb) {
23854                    // This service isn't far enough down on the LRU list to
23855                    // normally be a B service, but if we are low on RAM and it
23856                    // is large we want to force it down since we would prefer to
23857                    // keep launcher over it.
23858                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
23859                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
23860                        app.serviceHighRam = true;
23861                        app.serviceb = true;
23862                        //Slog.i(TAG, "ADJ " + app + " high ram!");
23863                    } else {
23864                        mNewNumAServiceProcs++;
23865                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
23866                    }
23867                } else {
23868                    app.serviceHighRam = false;
23869                }
23870            }
23871            if (app.serviceb) {
23872                adj = ProcessList.SERVICE_B_ADJ;
23873            }
23874        }
23875
23876        app.curRawAdj = adj;
23877
23878        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
23879        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
23880        if (adj > app.maxAdj) {
23881            adj = app.maxAdj;
23882            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
23883                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23884            }
23885        }
23886
23887        // Do final modification to adj.  Everything we do between here and applying
23888        // the final setAdj must be done in this function, because we will also use
23889        // it when computing the final cached adj later.  Note that we don't need to
23890        // worry about this for max adj above, since max adj will always be used to
23891        // keep it out of the cached vaues.
23892        app.curAdj = app.modifyRawOomAdj(adj);
23893        app.curSchedGroup = schedGroup;
23894        app.curProcState = procState;
23895        app.foregroundActivities = foregroundActivities;
23896
23897        return app.curRawAdj;
23898    }
23899
23900    /**
23901     * Record new PSS sample for a process.
23902     */
23903    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
23904            long rss, int statType, long pssDuration, long now) {
23905        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
23906                swapPss * 1024, rss * 1024, statType, procState, pssDuration);
23907        proc.lastPssTime = now;
23908        proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList);
23909        if (DEBUG_PSS) Slog.d(TAG_PSS,
23910                "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
23911                + " state=" + ProcessList.makeProcStateString(procState));
23912        if (proc.initialIdlePss == 0) {
23913            proc.initialIdlePss = pss;
23914        }
23915        proc.lastPss = pss;
23916        proc.lastSwapPss = swapPss;
23917        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
23918            proc.lastCachedPss = pss;
23919            proc.lastCachedSwapPss = swapPss;
23920        }
23921
23922        final SparseArray<Pair<Long, String>> watchUids
23923                = mMemWatchProcesses.getMap().get(proc.processName);
23924        Long check = null;
23925        if (watchUids != null) {
23926            Pair<Long, String> val = watchUids.get(proc.uid);
23927            if (val == null) {
23928                val = watchUids.get(0);
23929            }
23930            if (val != null) {
23931                check = val.first;
23932            }
23933        }
23934        if (check != null) {
23935            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
23936                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23937                if (!isDebuggable) {
23938                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
23939                        isDebuggable = true;
23940                    }
23941                }
23942                if (isDebuggable) {
23943                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
23944                    final ProcessRecord myProc = proc;
23945                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
23946                    mMemWatchDumpProcName = proc.processName;
23947                    mMemWatchDumpFile = heapdumpFile.toString();
23948                    mMemWatchDumpPid = proc.pid;
23949                    mMemWatchDumpUid = proc.uid;
23950                    BackgroundThread.getHandler().post(new Runnable() {
23951                        @Override
23952                        public void run() {
23953                            revokeUriPermission(ActivityThread.currentActivityThread()
23954                                            .getApplicationThread(),
23955                                    null, DumpHeapActivity.JAVA_URI,
23956                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
23957                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
23958                                    UserHandle.myUserId());
23959                            ParcelFileDescriptor fd = null;
23960                            try {
23961                                heapdumpFile.delete();
23962                                fd = ParcelFileDescriptor.open(heapdumpFile,
23963                                        ParcelFileDescriptor.MODE_CREATE |
23964                                                ParcelFileDescriptor.MODE_TRUNCATE |
23965                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
23966                                                ParcelFileDescriptor.MODE_APPEND);
23967                                IApplicationThread thread = myProc.thread;
23968                                if (thread != null) {
23969                                    try {
23970                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
23971                                                "Requesting dump heap from "
23972                                                + myProc + " to " + heapdumpFile);
23973                                        thread.dumpHeap(/* managed= */ true,
23974                                                /* mallocInfo= */ false, /* runGc= */ false,
23975                                                heapdumpFile.toString(), fd);
23976                                    } catch (RemoteException e) {
23977                                    }
23978                                }
23979                            } catch (FileNotFoundException e) {
23980                                e.printStackTrace();
23981                            } finally {
23982                                if (fd != null) {
23983                                    try {
23984                                        fd.close();
23985                                    } catch (IOException e) {
23986                                    }
23987                                }
23988                            }
23989                        }
23990                    });
23991                } else {
23992                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
23993                            + ", but debugging not enabled");
23994                }
23995            }
23996        }
23997    }
23998
23999    /**
24000     * Schedule PSS collection of a process.
24001     */
24002    boolean requestPssLocked(ProcessRecord proc, int procState) {
24003        if (mPendingPssProcesses.contains(proc)) {
24004            return false;
24005        }
24006        if (mPendingPssProcesses.size() == 0) {
24007            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
24008        }
24009        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
24010        proc.pssProcState = procState;
24011        proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE;
24012        mPendingPssProcesses.add(proc);
24013        return true;
24014    }
24015
24016    /**
24017     * Schedule PSS collection of all processes.
24018     */
24019    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
24020        if (!always) {
24021            if (now < (mLastFullPssTime +
24022                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
24023                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
24024                return;
24025            }
24026        }
24027        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs!  memLowered=" + memLowered);
24028        mLastFullPssTime = now;
24029        mFullPssPending = true;
24030        for (int i = mPendingPssProcesses.size() - 1; i >= 0; i--) {
24031            ProcessList.abortNextPssTime(mPendingPssProcesses.get(i).procStateMemTracker);;
24032        }
24033        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
24034        mPendingPssProcesses.clear();
24035        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24036            ProcessRecord app = mLruProcesses.get(i);
24037            if (app.thread == null
24038                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
24039                continue;
24040            }
24041            if (memLowered || (always && now >
24042                            app.lastStateTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
24043                    || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
24044                app.pssProcState = app.setProcState;
24045                app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
24046                        : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
24047                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24048                        app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24049                mPendingPssProcesses.add(app);
24050            }
24051        }
24052        if (!mBgHandler.hasMessages(COLLECT_PSS_BG_MSG)) {
24053            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
24054        }
24055    }
24056
24057    public void setTestPssMode(boolean enabled) {
24058        synchronized (this) {
24059            mTestPssMode = enabled;
24060            if (enabled) {
24061                // Whenever we enable the mode, we want to take a snapshot all of current
24062                // process mem use.
24063                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
24064            }
24065        }
24066    }
24067
24068    /**
24069     * Ask a given process to GC right now.
24070     */
24071    final void performAppGcLocked(ProcessRecord app) {
24072        try {
24073            app.lastRequestedGc = SystemClock.uptimeMillis();
24074            if (app.thread != null) {
24075                if (app.reportLowMemory) {
24076                    app.reportLowMemory = false;
24077                    app.thread.scheduleLowMemory();
24078                } else {
24079                    app.thread.processInBackground();
24080                }
24081            }
24082        } catch (Exception e) {
24083            // whatever.
24084        }
24085    }
24086
24087    /**
24088     * Returns true if things are idle enough to perform GCs.
24089     */
24090    private final boolean canGcNowLocked() {
24091        boolean processingBroadcasts = false;
24092        for (BroadcastQueue q : mBroadcastQueues) {
24093            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
24094                processingBroadcasts = true;
24095            }
24096        }
24097        return !processingBroadcasts
24098                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
24099    }
24100
24101    /**
24102     * Perform GCs on all processes that are waiting for it, but only
24103     * if things are idle.
24104     */
24105    final void performAppGcsLocked() {
24106        final int N = mProcessesToGc.size();
24107        if (N <= 0) {
24108            return;
24109        }
24110        if (canGcNowLocked()) {
24111            while (mProcessesToGc.size() > 0) {
24112                ProcessRecord proc = mProcessesToGc.remove(0);
24113                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
24114                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
24115                            <= SystemClock.uptimeMillis()) {
24116                        // To avoid spamming the system, we will GC processes one
24117                        // at a time, waiting a few seconds between each.
24118                        performAppGcLocked(proc);
24119                        scheduleAppGcsLocked();
24120                        return;
24121                    } else {
24122                        // It hasn't been long enough since we last GCed this
24123                        // process...  put it in the list to wait for its time.
24124                        addProcessToGcListLocked(proc);
24125                        break;
24126                    }
24127                }
24128            }
24129
24130            scheduleAppGcsLocked();
24131        }
24132    }
24133
24134    /**
24135     * If all looks good, perform GCs on all processes waiting for them.
24136     */
24137    final void performAppGcsIfAppropriateLocked() {
24138        if (canGcNowLocked()) {
24139            performAppGcsLocked();
24140            return;
24141        }
24142        // Still not idle, wait some more.
24143        scheduleAppGcsLocked();
24144    }
24145
24146    /**
24147     * Schedule the execution of all pending app GCs.
24148     */
24149    final void scheduleAppGcsLocked() {
24150        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
24151
24152        if (mProcessesToGc.size() > 0) {
24153            // Schedule a GC for the time to the next process.
24154            ProcessRecord proc = mProcessesToGc.get(0);
24155            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
24156
24157            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
24158            long now = SystemClock.uptimeMillis();
24159            if (when < (now+mConstants.GC_TIMEOUT)) {
24160                when = now + mConstants.GC_TIMEOUT;
24161            }
24162            mHandler.sendMessageAtTime(msg, when);
24163        }
24164    }
24165
24166    /**
24167     * Add a process to the array of processes waiting to be GCed.  Keeps the
24168     * list in sorted order by the last GC time.  The process can't already be
24169     * on the list.
24170     */
24171    final void addProcessToGcListLocked(ProcessRecord proc) {
24172        boolean added = false;
24173        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
24174            if (mProcessesToGc.get(i).lastRequestedGc <
24175                    proc.lastRequestedGc) {
24176                added = true;
24177                mProcessesToGc.add(i+1, proc);
24178                break;
24179            }
24180        }
24181        if (!added) {
24182            mProcessesToGc.add(0, proc);
24183        }
24184    }
24185
24186    /**
24187     * Set up to ask a process to GC itself.  This will either do it
24188     * immediately, or put it on the list of processes to gc the next
24189     * time things are idle.
24190     */
24191    final void scheduleAppGcLocked(ProcessRecord app) {
24192        long now = SystemClock.uptimeMillis();
24193        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
24194            return;
24195        }
24196        if (!mProcessesToGc.contains(app)) {
24197            addProcessToGcListLocked(app);
24198            scheduleAppGcsLocked();
24199        }
24200    }
24201
24202    final void checkExcessivePowerUsageLocked() {
24203        updateCpuStatsNow();
24204
24205        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
24206        boolean doCpuKills = true;
24207        if (mLastPowerCheckUptime == 0) {
24208            doCpuKills = false;
24209        }
24210        final long curUptime = SystemClock.uptimeMillis();
24211        final long uptimeSince = curUptime - mLastPowerCheckUptime;
24212        mLastPowerCheckUptime = curUptime;
24213        int i = mLruProcesses.size();
24214        while (i > 0) {
24215            i--;
24216            ProcessRecord app = mLruProcesses.get(i);
24217            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24218                if (app.lastCpuTime <= 0) {
24219                    continue;
24220                }
24221                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
24222                if (DEBUG_POWER) {
24223                    StringBuilder sb = new StringBuilder(128);
24224                    sb.append("CPU for ");
24225                    app.toShortString(sb);
24226                    sb.append(": over ");
24227                    TimeUtils.formatDuration(uptimeSince, sb);
24228                    sb.append(" used ");
24229                    TimeUtils.formatDuration(cputimeUsed, sb);
24230                    sb.append(" (");
24231                    sb.append((cputimeUsed*100)/uptimeSince);
24232                    sb.append("%)");
24233                    Slog.i(TAG_POWER, sb.toString());
24234                }
24235                // If the process has used too much CPU over the last duration, the
24236                // user probably doesn't want this, so kill!
24237                if (doCpuKills && uptimeSince > 0) {
24238                    // What is the limit for this process?
24239                    int cpuLimit;
24240                    long checkDur = curUptime - app.whenUnimportant;
24241                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
24242                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
24243                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
24244                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
24245                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
24246                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
24247                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
24248                    } else {
24249                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
24250                    }
24251                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
24252                        synchronized (stats) {
24253                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
24254                                    uptimeSince, cputimeUsed);
24255                        }
24256                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
24257                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
24258                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
24259                    }
24260                }
24261                app.lastCpuTime = app.curCpuTime;
24262            }
24263        }
24264    }
24265
24266    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
24267            long nowElapsed) {
24268        boolean success = true;
24269
24270        if (app.curRawAdj != app.setRawAdj) {
24271            app.setRawAdj = app.curRawAdj;
24272        }
24273
24274        int changes = 0;
24275
24276        if (app.curAdj != app.setAdj) {
24277            ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
24278            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
24279                String msg = "Set " + app.pid + " " + app.processName + " adj "
24280                        + app.curAdj + ": " + app.adjType;
24281                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24282            }
24283            app.setAdj = app.curAdj;
24284            app.verifiedAdj = ProcessList.INVALID_ADJ;
24285        }
24286
24287        if (app.setSchedGroup != app.curSchedGroup) {
24288            int oldSchedGroup = app.setSchedGroup;
24289            app.setSchedGroup = app.curSchedGroup;
24290            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
24291                String msg = "Setting sched group of " + app.processName
24292                        + " to " + app.curSchedGroup + ": " + app.adjType;
24293                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24294            }
24295            if (app.waitingToKill != null && app.curReceivers.isEmpty()
24296                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
24297                app.kill(app.waitingToKill, true);
24298                success = false;
24299            } else {
24300                int processGroup;
24301                switch (app.curSchedGroup) {
24302                    case ProcessList.SCHED_GROUP_BACKGROUND:
24303                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
24304                        break;
24305                    case ProcessList.SCHED_GROUP_TOP_APP:
24306                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
24307                        processGroup = THREAD_GROUP_TOP_APP;
24308                        break;
24309                    default:
24310                        processGroup = THREAD_GROUP_DEFAULT;
24311                        break;
24312                }
24313                long oldId = Binder.clearCallingIdentity();
24314                try {
24315                    setProcessGroup(app.pid, processGroup);
24316                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
24317                        // do nothing if we already switched to RT
24318                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
24319                            mVrController.onTopProcChangedLocked(app);
24320                            if (mUseFifoUiScheduling) {
24321                                // Switch UI pipeline for app to SCHED_FIFO
24322                                app.savedPriority = Process.getThreadPriority(app.pid);
24323                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
24324                                if (app.renderThreadTid != 0) {
24325                                    scheduleAsFifoPriority(app.renderThreadTid,
24326                                        /* suppressLogs */true);
24327                                    if (DEBUG_OOM_ADJ) {
24328                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
24329                                            app.renderThreadTid + ") to FIFO");
24330                                    }
24331                                } else {
24332                                    if (DEBUG_OOM_ADJ) {
24333                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
24334                                    }
24335                                }
24336                            } else {
24337                                // Boost priority for top app UI and render threads
24338                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
24339                                if (app.renderThreadTid != 0) {
24340                                    try {
24341                                        setThreadPriority(app.renderThreadTid,
24342                                                TOP_APP_PRIORITY_BOOST);
24343                                    } catch (IllegalArgumentException e) {
24344                                        // thread died, ignore
24345                                    }
24346                                }
24347                            }
24348                        }
24349                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
24350                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
24351                        mVrController.onTopProcChangedLocked(app);
24352                        if (mUseFifoUiScheduling) {
24353                            try {
24354                                // Reset UI pipeline to SCHED_OTHER
24355                                setThreadScheduler(app.pid, SCHED_OTHER, 0);
24356                                setThreadPriority(app.pid, app.savedPriority);
24357                                if (app.renderThreadTid != 0) {
24358                                    setThreadScheduler(app.renderThreadTid,
24359                                        SCHED_OTHER, 0);
24360                                    setThreadPriority(app.renderThreadTid, -4);
24361                                }
24362                            } catch (IllegalArgumentException e) {
24363                                Slog.w(TAG,
24364                                        "Failed to set scheduling policy, thread does not exist:\n"
24365                                                + e);
24366                            } catch (SecurityException e) {
24367                                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
24368                            }
24369                        } else {
24370                            // Reset priority for top app UI and render threads
24371                            setThreadPriority(app.pid, 0);
24372                            if (app.renderThreadTid != 0) {
24373                                setThreadPriority(app.renderThreadTid, 0);
24374                            }
24375                        }
24376                    }
24377                } catch (Exception e) {
24378                    if (false) {
24379                        Slog.w(TAG, "Failed setting process group of " + app.pid
24380                                + " to " + app.curSchedGroup);
24381                        Slog.w(TAG, "at location", e);
24382                    }
24383                } finally {
24384                    Binder.restoreCallingIdentity(oldId);
24385                }
24386            }
24387        }
24388        if (app.repForegroundActivities != app.foregroundActivities) {
24389            app.repForegroundActivities = app.foregroundActivities;
24390            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
24391        }
24392        if (app.repProcState != app.curProcState) {
24393            app.repProcState = app.curProcState;
24394            if (app.thread != null) {
24395                try {
24396                    if (false) {
24397                        //RuntimeException h = new RuntimeException("here");
24398                        Slog.i(TAG, "Sending new process state " + app.repProcState
24399                                + " to " + app /*, h*/);
24400                    }
24401                    app.thread.setProcessState(app.repProcState);
24402                } catch (RemoteException e) {
24403                }
24404            }
24405        }
24406        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
24407                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
24408            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
24409                // Experimental code to more aggressively collect pss while
24410                // running test...  the problem is that this tends to collect
24411                // the data right when a process is transitioning between process
24412                // states, which will tend to give noisy data.
24413                long start = SystemClock.uptimeMillis();
24414                long startTime = SystemClock.currentThreadTimeMillis();
24415                long pss = Debug.getPss(app.pid, mTmpLong, null);
24416                long endTime = SystemClock.currentThreadTimeMillis();
24417                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1],
24418                        mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now);
24419                mPendingPssProcesses.remove(app);
24420                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
24421                        + " to " + app.curProcState + ": "
24422                        + (SystemClock.uptimeMillis()-start) + "ms");
24423            }
24424            app.lastStateTime = now;
24425            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24426                    app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24427            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
24428                    + ProcessList.makeProcStateString(app.setProcState) + " to "
24429                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
24430                    + (app.nextPssTime-now) + ": " + app);
24431        } else {
24432            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
24433                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
24434                    mTestPssMode)))) {
24435                if (requestPssLocked(app, app.setProcState)) {
24436                    app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24437                            app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24438                }
24439            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
24440                    "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
24441        }
24442        if (app.setProcState != app.curProcState) {
24443            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
24444                String msg = "Proc state change of " + app.processName
24445                        + " to " + ProcessList.makeProcStateString(app.curProcState)
24446                        + " (" + app.curProcState + ")" + ": " + app.adjType;
24447                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24448            }
24449            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
24450            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
24451            if (setImportant && !curImportant) {
24452                // This app is no longer something we consider important enough to allow to
24453                // use arbitrary amounts of battery power.  Note
24454                // its current CPU time to later know to kill it if
24455                // it is not behaving well.
24456                app.whenUnimportant = now;
24457                app.lastCpuTime = 0;
24458            }
24459            // Inform UsageStats of important process state change
24460            // Must be called before updating setProcState
24461            maybeUpdateUsageStatsLocked(app, nowElapsed);
24462
24463            app.setProcState = app.curProcState;
24464            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24465                app.notCachedSinceIdle = false;
24466            }
24467            if (!doingAll) {
24468                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
24469            } else {
24470                app.procStateChanged = true;
24471            }
24472        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
24473                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
24474            // For apps that sit around for a long time in the interactive state, we need
24475            // to report this at least once a day so they don't go idle.
24476            maybeUpdateUsageStatsLocked(app, nowElapsed);
24477        }
24478
24479        if (changes != 0) {
24480            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24481                    "Changes in " + app + ": " + changes);
24482            int i = mPendingProcessChanges.size()-1;
24483            ProcessChangeItem item = null;
24484            while (i >= 0) {
24485                item = mPendingProcessChanges.get(i);
24486                if (item.pid == app.pid) {
24487                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24488                            "Re-using existing item: " + item);
24489                    break;
24490                }
24491                i--;
24492            }
24493            if (i < 0) {
24494                // No existing item in pending changes; need a new one.
24495                final int NA = mAvailProcessChanges.size();
24496                if (NA > 0) {
24497                    item = mAvailProcessChanges.remove(NA-1);
24498                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24499                            "Retrieving available item: " + item);
24500                } else {
24501                    item = new ProcessChangeItem();
24502                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24503                            "Allocating new item: " + item);
24504                }
24505                item.changes = 0;
24506                item.pid = app.pid;
24507                item.uid = app.info.uid;
24508                if (mPendingProcessChanges.size() == 0) {
24509                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24510                            "*** Enqueueing dispatch processes changed!");
24511                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
24512                }
24513                mPendingProcessChanges.add(item);
24514            }
24515            item.changes |= changes;
24516            item.foregroundActivities = app.repForegroundActivities;
24517            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24518                    "Item " + Integer.toHexString(System.identityHashCode(item))
24519                    + " " + app.toShortString() + ": changes=" + item.changes
24520                    + " foreground=" + item.foregroundActivities
24521                    + " type=" + app.adjType + " source=" + app.adjSource
24522                    + " target=" + app.adjTarget);
24523        }
24524
24525        return success;
24526    }
24527
24528    private boolean isEphemeralLocked(int uid) {
24529        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
24530        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
24531            return false;
24532        }
24533        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
24534                packages[0]);
24535    }
24536
24537    @VisibleForTesting
24538    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
24539        final UidRecord.ChangeItem pendingChange;
24540        if (uidRec == null || uidRec.pendingChange == null) {
24541            if (mPendingUidChanges.size() == 0) {
24542                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24543                        "*** Enqueueing dispatch uid changed!");
24544                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
24545            }
24546            final int NA = mAvailUidChanges.size();
24547            if (NA > 0) {
24548                pendingChange = mAvailUidChanges.remove(NA-1);
24549                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24550                        "Retrieving available item: " + pendingChange);
24551            } else {
24552                pendingChange = new UidRecord.ChangeItem();
24553                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24554                        "Allocating new item: " + pendingChange);
24555            }
24556            if (uidRec != null) {
24557                uidRec.pendingChange = pendingChange;
24558                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
24559                    // If this uid is going away, and we haven't yet reported it is gone,
24560                    // then do so now.
24561                    change |= UidRecord.CHANGE_IDLE;
24562                }
24563            } else if (uid < 0) {
24564                throw new IllegalArgumentException("No UidRecord or uid");
24565            }
24566            pendingChange.uidRecord = uidRec;
24567            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
24568            mPendingUidChanges.add(pendingChange);
24569        } else {
24570            pendingChange = uidRec.pendingChange;
24571            // If there is no change in idle or active state, then keep whatever was pending.
24572            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
24573                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
24574                        | UidRecord.CHANGE_ACTIVE));
24575            }
24576            // If there is no change in cached or uncached state, then keep whatever was pending.
24577            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
24578                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
24579                        | UidRecord.CHANGE_UNCACHED));
24580            }
24581            // If this is a report of the UID being gone, then we shouldn't keep any previous
24582            // report of it being active or cached.  (That is, a gone uid is never active,
24583            // and never cached.)
24584            if ((change & UidRecord.CHANGE_GONE) != 0) {
24585                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
24586                if (!uidRec.idle) {
24587                    // If this uid is going away, and we haven't yet reported it is gone,
24588                    // then do so now.
24589                    change |= UidRecord.CHANGE_IDLE;
24590                }
24591            }
24592        }
24593        pendingChange.change = change;
24594        pendingChange.processState = uidRec != null
24595                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
24596        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
24597        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
24598        if (uidRec != null) {
24599            uidRec.lastReportedChange = change;
24600            uidRec.updateLastDispatchedProcStateSeq(change);
24601        }
24602
24603        // Directly update the power manager, since we sit on top of it and it is critical
24604        // it be kept in sync (so wake locks will be held as soon as appropriate).
24605        if (mLocalPowerManager != null) {
24606            // TO DO: dispatch cached/uncached changes here, so we don't need to report
24607            // all proc state changes.
24608            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
24609                mLocalPowerManager.uidActive(pendingChange.uid);
24610            }
24611            if ((change & UidRecord.CHANGE_IDLE) != 0) {
24612                mLocalPowerManager.uidIdle(pendingChange.uid);
24613            }
24614            if ((change & UidRecord.CHANGE_GONE) != 0) {
24615                mLocalPowerManager.uidGone(pendingChange.uid);
24616            } else {
24617                mLocalPowerManager.updateUidProcState(pendingChange.uid,
24618                        pendingChange.processState);
24619            }
24620        }
24621    }
24622
24623    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
24624            String authority) {
24625        if (app == null) return;
24626        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
24627            UserState userState = mUserController.getStartedUserState(app.userId);
24628            if (userState == null) return;
24629            final long now = SystemClock.elapsedRealtime();
24630            Long lastReported = userState.mProviderLastReportedFg.get(authority);
24631            if (lastReported == null || lastReported < now - 60 * 1000L) {
24632                if (mSystemReady) {
24633                    // Cannot touch the user stats if not system ready
24634                    mUsageStatsService.reportContentProviderUsage(
24635                            authority, providerPkgName, app.userId);
24636                }
24637                userState.mProviderLastReportedFg.put(authority, now);
24638            }
24639        }
24640    }
24641
24642    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
24643        if (DEBUG_USAGE_STATS) {
24644            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
24645                    + "] state changes: old = " + app.setProcState + ", new = "
24646                    + app.curProcState);
24647        }
24648        if (mUsageStatsService == null) {
24649            return;
24650        }
24651        boolean isInteraction;
24652        // To avoid some abuse patterns, we are going to be careful about what we consider
24653        // to be an app interaction.  Being the top activity doesn't count while the display
24654        // is sleeping, nor do short foreground services.
24655        if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
24656            isInteraction = true;
24657            app.fgInteractionTime = 0;
24658        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
24659            if (app.fgInteractionTime == 0) {
24660                app.fgInteractionTime = nowElapsed;
24661                isInteraction = false;
24662            } else {
24663                isInteraction = nowElapsed > app.fgInteractionTime
24664                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
24665            }
24666        } else {
24667            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
24668            app.fgInteractionTime = 0;
24669        }
24670        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
24671                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
24672            app.interactionEventTime = nowElapsed;
24673            String[] packages = app.getPackageList();
24674            if (packages != null) {
24675                for (int i = 0; i < packages.length; i++) {
24676                    mUsageStatsService.reportEvent(packages[i], app.userId,
24677                            UsageEvents.Event.SYSTEM_INTERACTION);
24678                }
24679            }
24680        }
24681        app.reportedInteraction = isInteraction;
24682        if (!isInteraction) {
24683            app.interactionEventTime = 0;
24684        }
24685    }
24686
24687    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
24688        if (proc.thread != null) {
24689            if (proc.baseProcessTracker != null) {
24690                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
24691            }
24692        }
24693    }
24694
24695    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
24696            ProcessRecord TOP_APP, boolean doingAll, long now) {
24697        if (app.thread == null) {
24698            return false;
24699        }
24700
24701        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
24702
24703        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
24704    }
24705
24706    @GuardedBy("this")
24707    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
24708            boolean oomAdj) {
24709        if (isForeground != proc.foregroundServices) {
24710            proc.foregroundServices = isForeground;
24711            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
24712                    proc.info.uid);
24713            if (isForeground) {
24714                if (curProcs == null) {
24715                    curProcs = new ArrayList<ProcessRecord>();
24716                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
24717                }
24718                if (!curProcs.contains(proc)) {
24719                    curProcs.add(proc);
24720                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
24721                            proc.info.packageName, proc.info.uid);
24722                }
24723            } else {
24724                if (curProcs != null) {
24725                    if (curProcs.remove(proc)) {
24726                        mBatteryStatsService.noteEvent(
24727                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
24728                                proc.info.packageName, proc.info.uid);
24729                        if (curProcs.size() <= 0) {
24730                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
24731                        }
24732                    }
24733                }
24734            }
24735            if (oomAdj) {
24736                updateOomAdjLocked();
24737            }
24738        }
24739    }
24740
24741    private final ActivityRecord resumedAppLocked() {
24742        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
24743        String pkg;
24744        int uid;
24745        if (act != null) {
24746            pkg = act.packageName;
24747            uid = act.info.applicationInfo.uid;
24748        } else {
24749            pkg = null;
24750            uid = -1;
24751        }
24752        // Has the UID or resumed package name changed?
24753        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
24754                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
24755            if (mCurResumedPackage != null) {
24756                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
24757                        mCurResumedPackage, mCurResumedUid);
24758            }
24759            mCurResumedPackage = pkg;
24760            mCurResumedUid = uid;
24761            if (mCurResumedPackage != null) {
24762                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
24763                        mCurResumedPackage, mCurResumedUid);
24764            }
24765        }
24766        return act;
24767    }
24768
24769    /**
24770     * Update OomAdj for a specific process.
24771     * @param app The process to update
24772     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
24773     *                  if necessary, or skip.
24774     * @return whether updateOomAdjLocked(app) was successful.
24775     */
24776    @GuardedBy("this")
24777    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
24778        final ActivityRecord TOP_ACT = resumedAppLocked();
24779        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24780        final boolean wasCached = app.cached;
24781
24782        mAdjSeq++;
24783
24784        // This is the desired cached adjusment we want to tell it to use.
24785        // If our app is currently cached, we know it, and that is it.  Otherwise,
24786        // we don't know it yet, and it needs to now be cached we will then
24787        // need to do a complete oom adj.
24788        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
24789                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
24790        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
24791                SystemClock.uptimeMillis());
24792        if (oomAdjAll
24793                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
24794            // Changed to/from cached state, so apps after it in the LRU
24795            // list may also be changed.
24796            updateOomAdjLocked();
24797        }
24798        return success;
24799    }
24800
24801    @GuardedBy("this")
24802    final void updateOomAdjLocked() {
24803        final ActivityRecord TOP_ACT = resumedAppLocked();
24804        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24805        final long now = SystemClock.uptimeMillis();
24806        final long nowElapsed = SystemClock.elapsedRealtime();
24807        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
24808        final int N = mLruProcesses.size();
24809
24810        if (false) {
24811            RuntimeException e = new RuntimeException();
24812            e.fillInStackTrace();
24813            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
24814        }
24815
24816        // Reset state in all uid records.
24817        for (int i=mActiveUids.size()-1; i>=0; i--) {
24818            final UidRecord uidRec = mActiveUids.valueAt(i);
24819            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24820                    "Starting update of " + uidRec);
24821            uidRec.reset();
24822        }
24823
24824        mStackSupervisor.rankTaskLayersIfNeeded();
24825
24826        mAdjSeq++;
24827        mNewNumServiceProcs = 0;
24828        mNewNumAServiceProcs = 0;
24829
24830        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
24831        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
24832
24833        // Let's determine how many processes we have running vs.
24834        // how many slots we have for background processes; we may want
24835        // to put multiple processes in a slot of there are enough of
24836        // them.
24837        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
24838                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
24839        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
24840        if (numEmptyProcs > cachedProcessLimit) {
24841            // If there are more empty processes than our limit on cached
24842            // processes, then use the cached process limit for the factor.
24843            // This ensures that the really old empty processes get pushed
24844            // down to the bottom, so if we are running low on memory we will
24845            // have a better chance at keeping around more cached processes
24846            // instead of a gazillion empty processes.
24847            numEmptyProcs = cachedProcessLimit;
24848        }
24849        int emptyFactor = numEmptyProcs/numSlots;
24850        if (emptyFactor < 1) emptyFactor = 1;
24851        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
24852        if (cachedFactor < 1) cachedFactor = 1;
24853        int stepCached = 0;
24854        int stepEmpty = 0;
24855        int numCached = 0;
24856        int numEmpty = 0;
24857        int numTrimming = 0;
24858
24859        mNumNonCachedProcs = 0;
24860        mNumCachedHiddenProcs = 0;
24861
24862        // First update the OOM adjustment for each of the
24863        // application processes based on their current state.
24864        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
24865        int nextCachedAdj = curCachedAdj+1;
24866        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
24867        int nextEmptyAdj = curEmptyAdj+2;
24868        for (int i=N-1; i>=0; i--) {
24869            ProcessRecord app = mLruProcesses.get(i);
24870            if (!app.killedByAm && app.thread != null) {
24871                app.procStateChanged = false;
24872                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
24873
24874                // If we haven't yet assigned the final cached adj
24875                // to the process, do that now.
24876                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
24877                    switch (app.curProcState) {
24878                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
24879                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
24880                        case ActivityManager.PROCESS_STATE_CACHED_RECENT:
24881                            // This process is a cached process holding activities...
24882                            // assign it the next cached value for that type, and then
24883                            // step that cached level.
24884                            app.curRawAdj = curCachedAdj;
24885                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
24886                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
24887                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
24888                                    + ")");
24889                            if (curCachedAdj != nextCachedAdj) {
24890                                stepCached++;
24891                                if (stepCached >= cachedFactor) {
24892                                    stepCached = 0;
24893                                    curCachedAdj = nextCachedAdj;
24894                                    nextCachedAdj += 2;
24895                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
24896                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
24897                                    }
24898                                }
24899                            }
24900                            break;
24901                        default:
24902                            // For everything else, assign next empty cached process
24903                            // level and bump that up.  Note that this means that
24904                            // long-running services that have dropped down to the
24905                            // cached level will be treated as empty (since their process
24906                            // state is still as a service), which is what we want.
24907                            app.curRawAdj = curEmptyAdj;
24908                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
24909                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
24910                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
24911                                    + ")");
24912                            if (curEmptyAdj != nextEmptyAdj) {
24913                                stepEmpty++;
24914                                if (stepEmpty >= emptyFactor) {
24915                                    stepEmpty = 0;
24916                                    curEmptyAdj = nextEmptyAdj;
24917                                    nextEmptyAdj += 2;
24918                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
24919                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
24920                                    }
24921                                }
24922                            }
24923                            break;
24924                    }
24925                }
24926
24927                applyOomAdjLocked(app, true, now, nowElapsed);
24928
24929                // Count the number of process types.
24930                switch (app.curProcState) {
24931                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
24932                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
24933                        mNumCachedHiddenProcs++;
24934                        numCached++;
24935                        if (numCached > cachedProcessLimit) {
24936                            app.kill("cached #" + numCached, true);
24937                        }
24938                        break;
24939                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
24940                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
24941                                && app.lastActivityTime < oldTime) {
24942                            app.kill("empty for "
24943                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
24944                                    / 1000) + "s", true);
24945                        } else {
24946                            numEmpty++;
24947                            if (numEmpty > emptyProcessLimit) {
24948                                app.kill("empty #" + numEmpty, true);
24949                            }
24950                        }
24951                        break;
24952                    default:
24953                        mNumNonCachedProcs++;
24954                        break;
24955                }
24956
24957                if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
24958                    // If this is an isolated process, there are no services
24959                    // running in it, and it's not a special process with a
24960                    // custom entry point, then the process is no longer
24961                    // needed.  We agressively kill these because we can by
24962                    // definition not re-use the same process again, and it is
24963                    // good to avoid having whatever code was running in them
24964                    // left sitting around after no longer needed.
24965                    app.kill("isolated not needed", true);
24966                } else {
24967                    // Keeping this process, update its uid.
24968                    final UidRecord uidRec = app.uidRecord;
24969                    if (uidRec != null) {
24970                        uidRec.ephemeral = app.info.isInstantApp();
24971                        if (uidRec.curProcState > app.curProcState) {
24972                            uidRec.curProcState = app.curProcState;
24973                        }
24974                        if (app.foregroundServices) {
24975                            uidRec.foregroundServices = true;
24976                        }
24977                    }
24978                }
24979
24980                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
24981                        && !app.killedByAm) {
24982                    numTrimming++;
24983                }
24984            }
24985        }
24986
24987        incrementProcStateSeqAndNotifyAppsLocked();
24988
24989        mNumServiceProcs = mNewNumServiceProcs;
24990
24991        // Now determine the memory trimming level of background processes.
24992        // Unfortunately we need to start at the back of the list to do this
24993        // properly.  We only do this if the number of background apps we
24994        // are managing to keep around is less than half the maximum we desire;
24995        // if we are keeping a good number around, we'll let them use whatever
24996        // memory they want.
24997        final int numCachedAndEmpty = numCached + numEmpty;
24998        int memFactor;
24999        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
25000                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
25001            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
25002                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
25003            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
25004                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
25005            } else {
25006                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
25007            }
25008        } else {
25009            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
25010        }
25011        // We always allow the memory level to go up (better).  We only allow it to go
25012        // down if we are in a state where that is allowed, *and* the total number of processes
25013        // has gone down since last time.
25014        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
25015                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
25016                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
25017        if (memFactor > mLastMemoryLevel) {
25018            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
25019                memFactor = mLastMemoryLevel;
25020                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
25021            }
25022        }
25023        if (memFactor != mLastMemoryLevel) {
25024            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
25025        }
25026        mLastMemoryLevel = memFactor;
25027        mLastNumProcesses = mLruProcesses.size();
25028        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
25029        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
25030        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
25031            if (mLowRamStartTime == 0) {
25032                mLowRamStartTime = now;
25033            }
25034            int step = 0;
25035            int fgTrimLevel;
25036            switch (memFactor) {
25037                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
25038                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
25039                    break;
25040                case ProcessStats.ADJ_MEM_FACTOR_LOW:
25041                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
25042                    break;
25043                default:
25044                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
25045                    break;
25046            }
25047            int factor = numTrimming/3;
25048            int minFactor = 2;
25049            if (mHomeProcess != null) minFactor++;
25050            if (mPreviousProcess != null) minFactor++;
25051            if (factor < minFactor) factor = minFactor;
25052            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
25053            for (int i=N-1; i>=0; i--) {
25054                ProcessRecord app = mLruProcesses.get(i);
25055                if (allChanged || app.procStateChanged) {
25056                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
25057                    app.procStateChanged = false;
25058                }
25059                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
25060                        && !app.killedByAm) {
25061                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
25062                        try {
25063                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25064                                    "Trimming memory of " + app.processName + " to " + curLevel);
25065                            app.thread.scheduleTrimMemory(curLevel);
25066                        } catch (RemoteException e) {
25067                        }
25068                        if (false) {
25069                            // For now we won't do this; our memory trimming seems
25070                            // to be good enough at this point that destroying
25071                            // activities causes more harm than good.
25072                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
25073                                    && app != mHomeProcess && app != mPreviousProcess) {
25074                                // Need to do this on its own message because the stack may not
25075                                // be in a consistent state at this point.
25076                                // For these apps we will also finish their activities
25077                                // to help them free memory.
25078                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
25079                            }
25080                        }
25081                    }
25082                    app.trimMemoryLevel = curLevel;
25083                    step++;
25084                    if (step >= factor) {
25085                        step = 0;
25086                        switch (curLevel) {
25087                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
25088                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
25089                                break;
25090                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
25091                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
25092                                break;
25093                        }
25094                    }
25095                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
25096                        && !app.killedByAm) {
25097                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
25098                            && app.thread != null) {
25099                        try {
25100                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25101                                    "Trimming memory of heavy-weight " + app.processName
25102                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
25103                            app.thread.scheduleTrimMemory(
25104                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
25105                        } catch (RemoteException e) {
25106                        }
25107                    }
25108                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
25109                } else {
25110                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
25111                            || app.systemNoUi) && app.pendingUiClean) {
25112                        // If this application is now in the background and it
25113                        // had done UI, then give it the special trim level to
25114                        // have it free UI resources.
25115                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
25116                        if (app.trimMemoryLevel < level && app.thread != null) {
25117                            try {
25118                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25119                                        "Trimming memory of bg-ui " + app.processName
25120                                        + " to " + level);
25121                                app.thread.scheduleTrimMemory(level);
25122                            } catch (RemoteException e) {
25123                            }
25124                        }
25125                        app.pendingUiClean = false;
25126                    }
25127                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
25128                        try {
25129                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25130                                    "Trimming memory of fg " + app.processName
25131                                    + " to " + fgTrimLevel);
25132                            app.thread.scheduleTrimMemory(fgTrimLevel);
25133                        } catch (RemoteException e) {
25134                        }
25135                    }
25136                    app.trimMemoryLevel = fgTrimLevel;
25137                }
25138            }
25139        } else {
25140            if (mLowRamStartTime != 0) {
25141                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
25142                mLowRamStartTime = 0;
25143            }
25144            for (int i=N-1; i>=0; i--) {
25145                ProcessRecord app = mLruProcesses.get(i);
25146                if (allChanged || app.procStateChanged) {
25147                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
25148                    app.procStateChanged = false;
25149                }
25150                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
25151                        || app.systemNoUi) && app.pendingUiClean) {
25152                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
25153                            && app.thread != null) {
25154                        try {
25155                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25156                                    "Trimming memory of ui hidden " + app.processName
25157                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
25158                            app.thread.scheduleTrimMemory(
25159                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
25160                        } catch (RemoteException e) {
25161                        }
25162                    }
25163                    app.pendingUiClean = false;
25164                }
25165                app.trimMemoryLevel = 0;
25166            }
25167        }
25168
25169        if (mAlwaysFinishActivities) {
25170            // Need to do this on its own message because the stack may not
25171            // be in a consistent state at this point.
25172            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
25173        }
25174
25175        if (allChanged) {
25176            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
25177        }
25178
25179        ArrayList<UidRecord> becameIdle = null;
25180
25181        // Update from any uid changes.
25182        if (mLocalPowerManager != null) {
25183            mLocalPowerManager.startUidChanges();
25184        }
25185        for (int i=mActiveUids.size()-1; i>=0; i--) {
25186            final UidRecord uidRec = mActiveUids.valueAt(i);
25187            int uidChange = UidRecord.CHANGE_PROCSTATE;
25188            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
25189                    && (uidRec.setProcState != uidRec.curProcState
25190                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
25191                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
25192                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
25193                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
25194                        + " to " + uidRec.curWhitelist);
25195                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
25196                        && !uidRec.curWhitelist) {
25197                    // UID is now in the background (and not on the temp whitelist).  Was it
25198                    // previously in the foreground (or on the temp whitelist)?
25199                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
25200                            || uidRec.setWhitelist) {
25201                        uidRec.lastBackgroundTime = nowElapsed;
25202                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
25203                            // Note: the background settle time is in elapsed realtime, while
25204                            // the handler time base is uptime.  All this means is that we may
25205                            // stop background uids later than we had intended, but that only
25206                            // happens because the device was sleeping so we are okay anyway.
25207                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
25208                                    mConstants.BACKGROUND_SETTLE_TIME);
25209                        }
25210                    }
25211                    if (uidRec.idle && !uidRec.setIdle) {
25212                        uidChange = UidRecord.CHANGE_IDLE;
25213                        if (becameIdle == null) {
25214                            becameIdle = new ArrayList<>();
25215                        }
25216                        becameIdle.add(uidRec);
25217                    }
25218                } else {
25219                    if (uidRec.idle) {
25220                        uidChange = UidRecord.CHANGE_ACTIVE;
25221                        EventLogTags.writeAmUidActive(uidRec.uid);
25222                        uidRec.idle = false;
25223                    }
25224                    uidRec.lastBackgroundTime = 0;
25225                }
25226                final boolean wasCached = uidRec.setProcState
25227                        > ActivityManager.PROCESS_STATE_RECEIVER;
25228                final boolean isCached = uidRec.curProcState
25229                        > ActivityManager.PROCESS_STATE_RECEIVER;
25230                if (wasCached != isCached ||
25231                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
25232                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
25233                }
25234                uidRec.setProcState = uidRec.curProcState;
25235                uidRec.setWhitelist = uidRec.curWhitelist;
25236                uidRec.setIdle = uidRec.idle;
25237                enqueueUidChangeLocked(uidRec, -1, uidChange);
25238                noteUidProcessState(uidRec.uid, uidRec.curProcState);
25239                if (uidRec.foregroundServices) {
25240                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
25241                }
25242            }
25243        }
25244        if (mLocalPowerManager != null) {
25245            mLocalPowerManager.finishUidChanges();
25246        }
25247
25248        if (becameIdle != null) {
25249            // If we have any new uids that became idle this time, we need to make sure
25250            // they aren't left with running services.
25251            for (int i = becameIdle.size() - 1; i >= 0; i--) {
25252                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
25253            }
25254        }
25255
25256        if (mProcessStats.shouldWriteNowLocked(now)) {
25257            mHandler.post(new Runnable() {
25258                @Override public void run() {
25259                    synchronized (ActivityManagerService.this) {
25260                        mProcessStats.writeStateAsyncLocked();
25261                    }
25262                }
25263            });
25264        }
25265
25266        if (DEBUG_OOM_ADJ) {
25267            final long duration = SystemClock.uptimeMillis() - now;
25268            if (false) {
25269                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
25270                        new RuntimeException("here").fillInStackTrace());
25271            } else {
25272                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
25273            }
25274        }
25275    }
25276
25277    @Override
25278    public void makePackageIdle(String packageName, int userId) {
25279        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
25280                != PackageManager.PERMISSION_GRANTED) {
25281            String msg = "Permission Denial: makePackageIdle() from pid="
25282                    + Binder.getCallingPid()
25283                    + ", uid=" + Binder.getCallingUid()
25284                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
25285            Slog.w(TAG, msg);
25286            throw new SecurityException(msg);
25287        }
25288        final int callingPid = Binder.getCallingPid();
25289        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
25290                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
25291        long callingId = Binder.clearCallingIdentity();
25292        synchronized(this) {
25293            try {
25294                IPackageManager pm = AppGlobals.getPackageManager();
25295                int pkgUid = -1;
25296                try {
25297                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
25298                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
25299                } catch (RemoteException e) {
25300                }
25301                if (pkgUid == -1) {
25302                    throw new IllegalArgumentException("Unknown package name " + packageName);
25303                }
25304
25305                if (mLocalPowerManager != null) {
25306                    mLocalPowerManager.startUidChanges();
25307                }
25308                final int appId = UserHandle.getAppId(pkgUid);
25309                final int N = mActiveUids.size();
25310                for (int i=N-1; i>=0; i--) {
25311                    final UidRecord uidRec = mActiveUids.valueAt(i);
25312                    final long bgTime = uidRec.lastBackgroundTime;
25313                    if (bgTime > 0 && !uidRec.idle) {
25314                        if (UserHandle.getAppId(uidRec.uid) == appId) {
25315                            if (userId == UserHandle.USER_ALL ||
25316                                    userId == UserHandle.getUserId(uidRec.uid)) {
25317                                EventLogTags.writeAmUidIdle(uidRec.uid);
25318                                uidRec.idle = true;
25319                                uidRec.setIdle = true;
25320                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
25321                                        + " from package " + packageName + " user " + userId);
25322                                doStopUidLocked(uidRec.uid, uidRec);
25323                            }
25324                        }
25325                    }
25326                }
25327            } finally {
25328                if (mLocalPowerManager != null) {
25329                    mLocalPowerManager.finishUidChanges();
25330                }
25331                Binder.restoreCallingIdentity(callingId);
25332            }
25333        }
25334    }
25335
25336    final void idleUids() {
25337        synchronized (this) {
25338            final int N = mActiveUids.size();
25339            if (N <= 0) {
25340                return;
25341            }
25342            final long nowElapsed = SystemClock.elapsedRealtime();
25343            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
25344            long nextTime = 0;
25345            if (mLocalPowerManager != null) {
25346                mLocalPowerManager.startUidChanges();
25347            }
25348            for (int i=N-1; i>=0; i--) {
25349                final UidRecord uidRec = mActiveUids.valueAt(i);
25350                final long bgTime = uidRec.lastBackgroundTime;
25351                if (bgTime > 0 && !uidRec.idle) {
25352                    if (bgTime <= maxBgTime) {
25353                        EventLogTags.writeAmUidIdle(uidRec.uid);
25354                        uidRec.idle = true;
25355                        uidRec.setIdle = true;
25356                        doStopUidLocked(uidRec.uid, uidRec);
25357                    } else {
25358                        if (nextTime == 0 || nextTime > bgTime) {
25359                            nextTime = bgTime;
25360                        }
25361                    }
25362                }
25363            }
25364            if (mLocalPowerManager != null) {
25365                mLocalPowerManager.finishUidChanges();
25366            }
25367            if (nextTime > 0) {
25368                mHandler.removeMessages(IDLE_UIDS_MSG);
25369                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
25370                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
25371            }
25372        }
25373    }
25374
25375    /**
25376     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
25377     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
25378     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
25379     */
25380    @VisibleForTesting
25381    @GuardedBy("this")
25382    void incrementProcStateSeqAndNotifyAppsLocked() {
25383        if (mWaitForNetworkTimeoutMs <= 0) {
25384            return;
25385        }
25386        // Used for identifying which uids need to block for network.
25387        ArrayList<Integer> blockingUids = null;
25388        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
25389            final UidRecord uidRec = mActiveUids.valueAt(i);
25390            // If the network is not restricted for uid, then nothing to do here.
25391            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
25392                continue;
25393            }
25394            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
25395                continue;
25396            }
25397            // If process state is not changed, then there's nothing to do.
25398            if (uidRec.setProcState == uidRec.curProcState) {
25399                continue;
25400            }
25401            final int blockState = getBlockStateForUid(uidRec);
25402            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
25403            // there's nothing the app needs to do in this scenario.
25404            if (blockState == NETWORK_STATE_NO_CHANGE) {
25405                continue;
25406            }
25407            synchronized (uidRec.networkStateLock) {
25408                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
25409                if (blockState == NETWORK_STATE_BLOCK) {
25410                    if (blockingUids == null) {
25411                        blockingUids = new ArrayList<>();
25412                    }
25413                    blockingUids.add(uidRec.uid);
25414                } else {
25415                    if (DEBUG_NETWORK) {
25416                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
25417                                + " threads for uid: " + uidRec);
25418                    }
25419                    if (uidRec.waitingForNetwork) {
25420                        uidRec.networkStateLock.notifyAll();
25421                    }
25422                }
25423            }
25424        }
25425
25426        // There are no uids that need to block, so nothing more to do.
25427        if (blockingUids == null) {
25428            return;
25429        }
25430
25431        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
25432            final ProcessRecord app = mLruProcesses.get(i);
25433            if (!blockingUids.contains(app.uid)) {
25434                continue;
25435            }
25436            if (!app.killedByAm && app.thread != null) {
25437                final UidRecord uidRec = mActiveUids.get(app.uid);
25438                try {
25439                    if (DEBUG_NETWORK) {
25440                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
25441                                + uidRec);
25442                    }
25443                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
25444                } catch (RemoteException ignored) {
25445                }
25446            }
25447        }
25448    }
25449
25450    /**
25451     * Checks if the uid is coming from background to foreground or vice versa and returns
25452     * appropriate block state based on this.
25453     *
25454     * @return blockState based on whether the uid is coming from background to foreground or
25455     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
25456     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
25457     *         {@link #NETWORK_STATE_NO_CHANGE}.
25458     */
25459    @VisibleForTesting
25460    int getBlockStateForUid(UidRecord uidRec) {
25461        // Denotes whether uid's process state is currently allowed network access.
25462        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
25463                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
25464        // Denotes whether uid's process state was previously allowed network access.
25465        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
25466                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
25467
25468        // When the uid is coming to foreground, AMS should inform the app thread that it should
25469        // block for the network rules to get updated before launching an activity.
25470        if (!wasAllowed && isAllowed) {
25471            return NETWORK_STATE_BLOCK;
25472        }
25473        // When the uid is going to background, AMS should inform the app thread that if an
25474        // activity launch is blocked for the network rules to get updated, it should be unblocked.
25475        if (wasAllowed && !isAllowed) {
25476            return NETWORK_STATE_UNBLOCK;
25477        }
25478        return NETWORK_STATE_NO_CHANGE;
25479    }
25480
25481    final void runInBackgroundDisabled(int uid) {
25482        synchronized (this) {
25483            UidRecord uidRec = mActiveUids.get(uid);
25484            if (uidRec != null) {
25485                // This uid is actually running...  should it be considered background now?
25486                if (uidRec.idle) {
25487                    doStopUidLocked(uidRec.uid, uidRec);
25488                }
25489            } else {
25490                // This uid isn't actually running...  still send a report about it being "stopped".
25491                doStopUidLocked(uid, null);
25492            }
25493        }
25494    }
25495
25496    /**
25497     * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
25498     */
25499    void doStopUidForIdleUidsLocked() {
25500        final int size = mActiveUids.size();
25501        for (int i = 0; i < size; i++) {
25502            final int uid = mActiveUids.keyAt(i);
25503            if (UserHandle.isCore(uid)) {
25504                continue;
25505            }
25506            final UidRecord uidRec = mActiveUids.valueAt(i);
25507            if (!uidRec.idle) {
25508                continue;
25509            }
25510            doStopUidLocked(uidRec.uid, uidRec);
25511        }
25512    }
25513
25514    final void doStopUidLocked(int uid, final UidRecord uidRec) {
25515        mServices.stopInBackgroundLocked(uid);
25516        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
25517    }
25518
25519    /**
25520     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25521     */
25522    @GuardedBy("this")
25523    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
25524            long duration, String tag) {
25525        if (DEBUG_WHITELISTS) {
25526            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
25527                    + targetUid + ", " + duration + ")");
25528        }
25529
25530        synchronized (mPidsSelfLocked) {
25531            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
25532            if (pr == null) {
25533                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
25534                        + callerPid);
25535                return;
25536            }
25537            if (!pr.whitelistManager) {
25538                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
25539                        != PackageManager.PERMISSION_GRANTED) {
25540                    if (DEBUG_WHITELISTS) {
25541                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
25542                                + ": pid " + callerPid + " is not allowed");
25543                    }
25544                    return;
25545                }
25546            }
25547        }
25548
25549        tempWhitelistUidLocked(targetUid, duration, tag);
25550    }
25551
25552    /**
25553     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25554     */
25555    @GuardedBy("this")
25556    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
25557        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
25558        setUidTempWhitelistStateLocked(targetUid, true);
25559        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
25560    }
25561
25562    void pushTempWhitelist() {
25563        final int N;
25564        final PendingTempWhitelist[] list;
25565
25566        // First copy out the pending changes...  we need to leave them in the map for now,
25567        // in case someone needs to check what is coming up while we don't have the lock held.
25568        synchronized(this) {
25569            N = mPendingTempWhitelist.size();
25570            list = new PendingTempWhitelist[N];
25571            for (int i = 0; i < N; i++) {
25572                list[i] = mPendingTempWhitelist.valueAt(i);
25573            }
25574        }
25575
25576        // Now safely dispatch changes to device idle controller.
25577        for (int i = 0; i < N; i++) {
25578            PendingTempWhitelist ptw = list[i];
25579            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
25580                    ptw.duration, true, ptw.tag);
25581        }
25582
25583        // And now we can safely remove them from the map.
25584        synchronized(this) {
25585            for (int i = 0; i < N; i++) {
25586                PendingTempWhitelist ptw = list[i];
25587                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
25588                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
25589                    mPendingTempWhitelist.removeAt(index);
25590                }
25591            }
25592        }
25593    }
25594
25595    @GuardedBy("this")
25596    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
25597        boolean changed = false;
25598        for (int i=mActiveUids.size()-1; i>=0; i--) {
25599            final UidRecord uidRec = mActiveUids.valueAt(i);
25600            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
25601                uidRec.curWhitelist = onWhitelist;
25602                changed = true;
25603            }
25604        }
25605        if (changed) {
25606            updateOomAdjLocked();
25607        }
25608    }
25609
25610    @GuardedBy("this")
25611    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
25612        boolean changed = false;
25613        final UidRecord uidRec = mActiveUids.get(uid);
25614        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
25615            uidRec.curWhitelist = onWhitelist;
25616            updateOomAdjLocked();
25617        }
25618    }
25619
25620    final void trimApplications() {
25621        synchronized (this) {
25622            int i;
25623
25624            // First remove any unused application processes whose package
25625            // has been removed.
25626            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
25627                final ProcessRecord app = mRemovedProcesses.get(i);
25628                if (app.activities.size() == 0 && app.recentTasks.size() == 0
25629                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
25630                    Slog.i(
25631                        TAG, "Exiting empty application process "
25632                        + app.toShortString() + " ("
25633                        + (app.thread != null ? app.thread.asBinder() : null)
25634                        + ")\n");
25635                    if (app.pid > 0 && app.pid != MY_PID) {
25636                        app.kill("empty", false);
25637                    } else if (app.thread != null) {
25638                        try {
25639                            app.thread.scheduleExit();
25640                        } catch (Exception e) {
25641                            // Ignore exceptions.
25642                        }
25643                    }
25644                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
25645                    mRemovedProcesses.remove(i);
25646
25647                    if (app.persistent) {
25648                        addAppLocked(app.info, null, false, null /* ABI override */);
25649                    }
25650                }
25651            }
25652
25653            // Now update the oom adj for all processes.
25654            updateOomAdjLocked();
25655        }
25656    }
25657
25658    /** This method sends the specified signal to each of the persistent apps */
25659    public void signalPersistentProcesses(int sig) throws RemoteException {
25660        if (sig != SIGNAL_USR1) {
25661            throw new SecurityException("Only SIGNAL_USR1 is allowed");
25662        }
25663
25664        synchronized (this) {
25665            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
25666                    != PackageManager.PERMISSION_GRANTED) {
25667                throw new SecurityException("Requires permission "
25668                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
25669            }
25670
25671            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
25672                ProcessRecord r = mLruProcesses.get(i);
25673                if (r.thread != null && r.persistent) {
25674                    sendSignal(r.pid, sig);
25675                }
25676            }
25677        }
25678    }
25679
25680    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
25681        if (proc == null || proc == mProfileProc) {
25682            proc = mProfileProc;
25683            profileType = mProfileType;
25684            clearProfilerLocked();
25685        }
25686        if (proc == null) {
25687            return;
25688        }
25689        try {
25690            proc.thread.profilerControl(false, null, profileType);
25691        } catch (RemoteException e) {
25692            throw new IllegalStateException("Process disappeared");
25693        }
25694    }
25695
25696    private void clearProfilerLocked() {
25697        if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
25698            try {
25699                mProfilerInfo.profileFd.close();
25700            } catch (IOException e) {
25701            }
25702        }
25703        mProfileApp = null;
25704        mProfileProc = null;
25705        mProfilerInfo = null;
25706    }
25707
25708    public boolean profileControl(String process, int userId, boolean start,
25709            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
25710
25711        try {
25712            synchronized (this) {
25713                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
25714                // its own permission.
25715                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25716                        != PackageManager.PERMISSION_GRANTED) {
25717                    throw new SecurityException("Requires permission "
25718                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25719                }
25720
25721                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
25722                    throw new IllegalArgumentException("null profile info or fd");
25723                }
25724
25725                ProcessRecord proc = null;
25726                if (process != null) {
25727                    proc = findProcessLocked(process, userId, "profileControl");
25728                }
25729
25730                if (start && (proc == null || proc.thread == null)) {
25731                    throw new IllegalArgumentException("Unknown process: " + process);
25732                }
25733
25734                if (start) {
25735                    stopProfilerLocked(null, 0);
25736                    setProfileApp(proc.info, proc.processName, profilerInfo);
25737                    mProfileProc = proc;
25738                    mProfileType = profileType;
25739                    ParcelFileDescriptor fd = profilerInfo.profileFd;
25740                    try {
25741                        fd = fd.dup();
25742                    } catch (IOException e) {
25743                        fd = null;
25744                    }
25745                    profilerInfo.profileFd = fd;
25746                    proc.thread.profilerControl(start, profilerInfo, profileType);
25747                    fd = null;
25748                    try {
25749                        mProfilerInfo.profileFd.close();
25750                    } catch (IOException e) {
25751                    }
25752                    mProfilerInfo.profileFd = null;
25753
25754                    if (proc.pid == MY_PID) {
25755                        // When profiling the system server itself, avoid closing the file
25756                        // descriptor, as profilerControl will not create a copy.
25757                        // Note: it is also not correct to just set profileFd to null, as the
25758                        //       whole ProfilerInfo instance is passed down!
25759                        profilerInfo = null;
25760                    }
25761                } else {
25762                    stopProfilerLocked(proc, profileType);
25763                    if (profilerInfo != null && profilerInfo.profileFd != null) {
25764                        try {
25765                            profilerInfo.profileFd.close();
25766                        } catch (IOException e) {
25767                        }
25768                    }
25769                }
25770
25771                return true;
25772            }
25773        } catch (RemoteException e) {
25774            throw new IllegalStateException("Process disappeared");
25775        } finally {
25776            if (profilerInfo != null && profilerInfo.profileFd != null) {
25777                try {
25778                    profilerInfo.profileFd.close();
25779                } catch (IOException e) {
25780                }
25781            }
25782        }
25783    }
25784
25785    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
25786        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
25787                userId, true, ALLOW_FULL_ONLY, callName, null);
25788        ProcessRecord proc = null;
25789        try {
25790            int pid = Integer.parseInt(process);
25791            synchronized (mPidsSelfLocked) {
25792                proc = mPidsSelfLocked.get(pid);
25793            }
25794        } catch (NumberFormatException e) {
25795        }
25796
25797        if (proc == null) {
25798            ArrayMap<String, SparseArray<ProcessRecord>> all
25799                    = mProcessNames.getMap();
25800            SparseArray<ProcessRecord> procs = all.get(process);
25801            if (procs != null && procs.size() > 0) {
25802                proc = procs.valueAt(0);
25803                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
25804                    for (int i=1; i<procs.size(); i++) {
25805                        ProcessRecord thisProc = procs.valueAt(i);
25806                        if (thisProc.userId == userId) {
25807                            proc = thisProc;
25808                            break;
25809                        }
25810                    }
25811                }
25812            }
25813        }
25814
25815        return proc;
25816    }
25817
25818    public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
25819            boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
25820
25821        try {
25822            synchronized (this) {
25823                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
25824                // its own permission (same as profileControl).
25825                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25826                        != PackageManager.PERMISSION_GRANTED) {
25827                    throw new SecurityException("Requires permission "
25828                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25829                }
25830
25831                if (fd == null) {
25832                    throw new IllegalArgumentException("null fd");
25833                }
25834
25835                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
25836                if (proc == null || proc.thread == null) {
25837                    throw new IllegalArgumentException("Unknown process: " + process);
25838                }
25839
25840                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25841                if (!isDebuggable) {
25842                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25843                        throw new SecurityException("Process not debuggable: " + proc);
25844                    }
25845                }
25846
25847                proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
25848                fd = null;
25849                return true;
25850            }
25851        } catch (RemoteException e) {
25852            throw new IllegalStateException("Process disappeared");
25853        } finally {
25854            if (fd != null) {
25855                try {
25856                    fd.close();
25857                } catch (IOException e) {
25858                }
25859            }
25860        }
25861    }
25862
25863    @Override
25864    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
25865            String reportPackage) {
25866        if (processName != null) {
25867            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
25868                    "setDumpHeapDebugLimit()");
25869        } else {
25870            synchronized (mPidsSelfLocked) {
25871                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
25872                if (proc == null) {
25873                    throw new SecurityException("No process found for calling pid "
25874                            + Binder.getCallingPid());
25875                }
25876                if (!Build.IS_DEBUGGABLE
25877                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25878                    throw new SecurityException("Not running a debuggable build");
25879                }
25880                processName = proc.processName;
25881                uid = proc.uid;
25882                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
25883                    throw new SecurityException("Package " + reportPackage + " is not running in "
25884                            + proc);
25885                }
25886            }
25887        }
25888        synchronized (this) {
25889            if (maxMemSize > 0) {
25890                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
25891            } else {
25892                if (uid != 0) {
25893                    mMemWatchProcesses.remove(processName, uid);
25894                } else {
25895                    mMemWatchProcesses.getMap().remove(processName);
25896                }
25897            }
25898        }
25899    }
25900
25901    @Override
25902    public void dumpHeapFinished(String path) {
25903        synchronized (this) {
25904            if (Binder.getCallingPid() != mMemWatchDumpPid) {
25905                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
25906                        + " does not match last pid " + mMemWatchDumpPid);
25907                return;
25908            }
25909            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
25910                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
25911                        + " does not match last path " + mMemWatchDumpFile);
25912                return;
25913            }
25914            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
25915            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
25916
25917            // Forced gc to clean up the remnant hprof fd.
25918            Runtime.getRuntime().gc();
25919        }
25920    }
25921
25922    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
25923    public void monitor() {
25924        synchronized (this) { }
25925    }
25926
25927    void onCoreSettingsChange(Bundle settings) {
25928        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
25929            ProcessRecord processRecord = mLruProcesses.get(i);
25930            try {
25931                if (processRecord.thread != null) {
25932                    processRecord.thread.setCoreSettings(settings);
25933                }
25934            } catch (RemoteException re) {
25935                /* ignore */
25936            }
25937        }
25938    }
25939
25940    // Multi-user methods
25941
25942    /**
25943     * Start user, if its not already running, but don't bring it to foreground.
25944     */
25945    @Override
25946    public boolean startUserInBackground(final int userId) {
25947        return startUserInBackgroundWithListener(userId, null);
25948    }
25949
25950    @Override
25951    public boolean startUserInBackgroundWithListener(final int userId,
25952                @Nullable IProgressListener unlockListener) {
25953        return mUserController.startUser(userId, /* foreground */ false, unlockListener);
25954    }
25955
25956    @Override
25957    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
25958        return mUserController.unlockUser(userId, token, secret, listener);
25959    }
25960
25961    @Override
25962    public boolean switchUser(final int targetUserId) {
25963        return mUserController.switchUser(targetUserId);
25964    }
25965
25966    @Override
25967    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
25968        return mUserController.stopUser(userId, force, callback);
25969    }
25970
25971    @Override
25972    public UserInfo getCurrentUser() {
25973        return mUserController.getCurrentUser();
25974    }
25975
25976    String getStartedUserState(int userId) {
25977        final UserState userState = mUserController.getStartedUserState(userId);
25978        return UserState.stateToString(userState.state);
25979    }
25980
25981    @Override
25982    public boolean isUserRunning(int userId, int flags) {
25983        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
25984                && checkCallingPermission(INTERACT_ACROSS_USERS)
25985                    != PackageManager.PERMISSION_GRANTED) {
25986            String msg = "Permission Denial: isUserRunning() from pid="
25987                    + Binder.getCallingPid()
25988                    + ", uid=" + Binder.getCallingUid()
25989                    + " requires " + INTERACT_ACROSS_USERS;
25990            Slog.w(TAG, msg);
25991            throw new SecurityException(msg);
25992        }
25993        return mUserController.isUserRunning(userId, flags);
25994    }
25995
25996    @Override
25997    public int[] getRunningUserIds() {
25998        if (checkCallingPermission(INTERACT_ACROSS_USERS)
25999                != PackageManager.PERMISSION_GRANTED) {
26000            String msg = "Permission Denial: isUserRunning() from pid="
26001                    + Binder.getCallingPid()
26002                    + ", uid=" + Binder.getCallingUid()
26003                    + " requires " + INTERACT_ACROSS_USERS;
26004            Slog.w(TAG, msg);
26005            throw new SecurityException(msg);
26006        }
26007        return mUserController.getStartedUserArray();
26008    }
26009
26010    @Override
26011    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
26012        mUserController.registerUserSwitchObserver(observer, name);
26013    }
26014
26015    @Override
26016    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
26017        mUserController.unregisterUserSwitchObserver(observer);
26018    }
26019
26020    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
26021        if (info == null) return null;
26022        ApplicationInfo newInfo = new ApplicationInfo(info);
26023        newInfo.initForUser(userId);
26024        return newInfo;
26025    }
26026
26027    public boolean isUserStopped(int userId) {
26028        return mUserController.getStartedUserState(userId) == null;
26029    }
26030
26031    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
26032        if (aInfo == null
26033                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
26034            return aInfo;
26035        }
26036
26037        ActivityInfo info = new ActivityInfo(aInfo);
26038        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
26039        return info;
26040    }
26041
26042    private boolean processSanityChecksLocked(ProcessRecord process) {
26043        if (process == null || process.thread == null) {
26044            return false;
26045        }
26046
26047        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26048        if (!isDebuggable) {
26049            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26050                return false;
26051            }
26052        }
26053
26054        return true;
26055    }
26056
26057    public boolean startBinderTracking() throws RemoteException {
26058        synchronized (this) {
26059            mBinderTransactionTrackingEnabled = true;
26060            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
26061            // permission (same as profileControl).
26062            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26063                    != PackageManager.PERMISSION_GRANTED) {
26064                throw new SecurityException("Requires permission "
26065                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26066            }
26067
26068            for (int i = 0; i < mLruProcesses.size(); i++) {
26069                ProcessRecord process = mLruProcesses.get(i);
26070                if (!processSanityChecksLocked(process)) {
26071                    continue;
26072                }
26073                try {
26074                    process.thread.startBinderTracking();
26075                } catch (RemoteException e) {
26076                    Log.v(TAG, "Process disappared");
26077                }
26078            }
26079            return true;
26080        }
26081    }
26082
26083    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
26084        try {
26085            synchronized (this) {
26086                mBinderTransactionTrackingEnabled = false;
26087                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
26088                // permission (same as profileControl).
26089                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26090                        != PackageManager.PERMISSION_GRANTED) {
26091                    throw new SecurityException("Requires permission "
26092                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26093                }
26094
26095                if (fd == null) {
26096                    throw new IllegalArgumentException("null fd");
26097                }
26098
26099                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
26100                pw.println("Binder transaction traces for all processes.\n");
26101                for (ProcessRecord process : mLruProcesses) {
26102                    if (!processSanityChecksLocked(process)) {
26103                        continue;
26104                    }
26105
26106                    pw.println("Traces for process: " + process.processName);
26107                    pw.flush();
26108                    try {
26109                        TransferPipe tp = new TransferPipe();
26110                        try {
26111                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
26112                            tp.go(fd.getFileDescriptor());
26113                        } finally {
26114                            tp.kill();
26115                        }
26116                    } catch (IOException e) {
26117                        pw.println("Failure while dumping IPC traces from " + process +
26118                                ".  Exception: " + e);
26119                        pw.flush();
26120                    } catch (RemoteException e) {
26121                        pw.println("Got a RemoteException while dumping IPC traces from " +
26122                                process + ".  Exception: " + e);
26123                        pw.flush();
26124                    }
26125                }
26126                fd = null;
26127                return true;
26128            }
26129        } finally {
26130            if (fd != null) {
26131                try {
26132                    fd.close();
26133                } catch (IOException e) {
26134                }
26135            }
26136        }
26137    }
26138
26139    @VisibleForTesting
26140    final class LocalService extends ActivityManagerInternal {
26141        @Override
26142        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
26143                int targetUserId) {
26144            synchronized (ActivityManagerService.this) {
26145                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
26146                        targetPkg, intent, null, targetUserId);
26147            }
26148        }
26149
26150        @Override
26151        public String checkContentProviderAccess(String authority, int userId) {
26152            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
26153        }
26154
26155        @Override
26156        public void onWakefulnessChanged(int wakefulness) {
26157            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
26158        }
26159
26160        @Override
26161        public boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
26162                String processName, String abiOverride, int uid, Runnable crashHandler) {
26163            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
26164                    processName, abiOverride, uid, crashHandler);
26165        }
26166
26167        @Override
26168        public SleepToken acquireSleepToken(String tag, int displayId) {
26169            Preconditions.checkNotNull(tag);
26170            return ActivityManagerService.this.acquireSleepToken(tag, displayId);
26171        }
26172
26173        @Override
26174        public ComponentName getHomeActivityForUser(int userId) {
26175            synchronized (ActivityManagerService.this) {
26176                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
26177                return homeActivity == null ? null : homeActivity.realActivity;
26178            }
26179        }
26180
26181        @Override
26182        public void onUserRemoved(int userId) {
26183            synchronized (ActivityManagerService.this) {
26184                ActivityManagerService.this.onUserStoppedLocked(userId);
26185            }
26186            mBatteryStatsService.onUserRemoved(userId);
26187            mUserController.onUserRemoved(userId);
26188        }
26189
26190        @Override
26191        public void onLocalVoiceInteractionStarted(IBinder activity,
26192                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
26193            synchronized (ActivityManagerService.this) {
26194                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
26195                        voiceSession, voiceInteractor);
26196            }
26197        }
26198
26199        @Override
26200        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
26201            synchronized (ActivityManagerService.this) {
26202                mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
26203                        reasons, timestamp);
26204            }
26205        }
26206
26207        @Override
26208        public void notifyAppTransitionFinished() {
26209            synchronized (ActivityManagerService.this) {
26210                mStackSupervisor.notifyAppTransitionDone();
26211            }
26212        }
26213
26214        @Override
26215        public void notifyAppTransitionCancelled() {
26216            synchronized (ActivityManagerService.this) {
26217                mStackSupervisor.notifyAppTransitionDone();
26218            }
26219        }
26220
26221        @Override
26222        public List<IBinder> getTopVisibleActivities() {
26223            synchronized (ActivityManagerService.this) {
26224                return mStackSupervisor.getTopVisibleActivities();
26225            }
26226        }
26227
26228        @Override
26229        public void notifyDockedStackMinimizedChanged(boolean minimized) {
26230            synchronized (ActivityManagerService.this) {
26231                mStackSupervisor.setDockedStackMinimized(minimized);
26232            }
26233        }
26234
26235        @Override
26236        public void killForegroundAppsForUser(int userHandle) {
26237            synchronized (ActivityManagerService.this) {
26238                final ArrayList<ProcessRecord> procs = new ArrayList<>();
26239                final int NP = mProcessNames.getMap().size();
26240                for (int ip = 0; ip < NP; ip++) {
26241                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
26242                    final int NA = apps.size();
26243                    for (int ia = 0; ia < NA; ia++) {
26244                        final ProcessRecord app = apps.valueAt(ia);
26245                        if (app.persistent) {
26246                            // We don't kill persistent processes.
26247                            continue;
26248                        }
26249                        if (app.removed) {
26250                            procs.add(app);
26251                        } else if (app.userId == userHandle && app.foregroundActivities) {
26252                            app.removed = true;
26253                            procs.add(app);
26254                        }
26255                    }
26256                }
26257
26258                final int N = procs.size();
26259                for (int i = 0; i < N; i++) {
26260                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
26261                }
26262            }
26263        }
26264
26265        @Override
26266        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
26267                long duration) {
26268            if (!(target instanceof PendingIntentRecord)) {
26269                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
26270                return;
26271            }
26272            synchronized (ActivityManagerService.this) {
26273                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
26274            }
26275        }
26276
26277        @Override
26278        public void setDeviceIdleWhitelist(int[] appids) {
26279            synchronized (ActivityManagerService.this) {
26280                mDeviceIdleWhitelist = appids;
26281            }
26282        }
26283
26284        @Override
26285        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
26286            synchronized (ActivityManagerService.this) {
26287                mDeviceIdleTempWhitelist = appids;
26288                setAppIdTempWhitelistStateLocked(changingAppId, adding);
26289            }
26290        }
26291
26292        @Override
26293        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
26294                int userId) {
26295            Preconditions.checkNotNull(values, "Configuration must not be null");
26296            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
26297            synchronized (ActivityManagerService.this) {
26298                updateConfigurationLocked(values, null, false, true, userId,
26299                        false /* deferResume */);
26300            }
26301        }
26302
26303        @Override
26304        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
26305                Bundle bOptions) {
26306            Preconditions.checkNotNull(intents, "intents");
26307            final String[] resolvedTypes = new String[intents.length];
26308
26309            // UID of the package on user userId.
26310            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
26311            // packageUid may not be initialized.
26312            int packageUid = 0;
26313            final long ident = Binder.clearCallingIdentity();
26314
26315            try {
26316                for (int i = 0; i < intents.length; i++) {
26317                    resolvedTypes[i] =
26318                            intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
26319                }
26320
26321                packageUid = AppGlobals.getPackageManager().getPackageUid(
26322                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
26323            } catch (RemoteException e) {
26324                // Shouldn't happen.
26325            } finally {
26326                Binder.restoreCallingIdentity(ident);
26327            }
26328
26329            synchronized (ActivityManagerService.this) {
26330                return mActivityStartController.startActivitiesInPackage(
26331                        packageUid, packageName,
26332                        intents, resolvedTypes, null /* resultTo */,
26333                        SafeActivityOptions.fromBundle(bOptions), userId,
26334                        false /* validateIncomingUser */);
26335            }
26336        }
26337
26338        @Override
26339        public int getUidProcessState(int uid) {
26340            return getUidState(uid);
26341        }
26342
26343        @Override
26344        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
26345            synchronized (ActivityManagerService.this) {
26346
26347                // We might change the visibilities here, so prepare an empty app transition which
26348                // might be overridden later if we actually change visibilities.
26349                final boolean wasTransitionSet =
26350                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
26351                if (!wasTransitionSet) {
26352                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
26353                            false /* alwaysKeepCurrent */);
26354                }
26355                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
26356
26357                // If there was a transition set already we don't want to interfere with it as we
26358                // might be starting it too early.
26359                if (!wasTransitionSet) {
26360                    mWindowManager.executeAppTransition();
26361                }
26362            }
26363            if (callback != null) {
26364                callback.run();
26365            }
26366        }
26367
26368        @Override
26369        public boolean isSystemReady() {
26370            // no need to synchronize(this) just to read & return the value
26371            return mSystemReady;
26372        }
26373
26374        @Override
26375        public void notifyKeyguardTrustedChanged() {
26376            synchronized (ActivityManagerService.this) {
26377                if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
26378                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
26379                }
26380            }
26381        }
26382
26383        /**
26384         * Sets if the given pid has an overlay UI or not.
26385         *
26386         * @param pid The pid we are setting overlay UI for.
26387         * @param hasOverlayUi True if the process has overlay UI.
26388         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
26389         */
26390        @Override
26391        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
26392            synchronized (ActivityManagerService.this) {
26393                final ProcessRecord pr;
26394                synchronized (mPidsSelfLocked) {
26395                    pr = mPidsSelfLocked.get(pid);
26396                    if (pr == null) {
26397                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
26398                        return;
26399                    }
26400                }
26401                if (pr.hasOverlayUi == hasOverlayUi) {
26402                    return;
26403                }
26404                pr.hasOverlayUi = hasOverlayUi;
26405                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
26406                updateOomAdjLocked(pr, true);
26407            }
26408        }
26409
26410        @Override
26411        public void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
26412            ActivityManagerService.this.setRunningRemoteAnimation(pid, runningRemoteAnimation);
26413        }
26414
26415        /**
26416         * Called after the network policy rules are updated by
26417         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
26418         * and {@param procStateSeq}.
26419         */
26420        @Override
26421        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
26422            if (DEBUG_NETWORK) {
26423                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
26424                        + uid + " seq: " + procStateSeq);
26425            }
26426            UidRecord record;
26427            synchronized (ActivityManagerService.this) {
26428                record = mActiveUids.get(uid);
26429                if (record == null) {
26430                    if (DEBUG_NETWORK) {
26431                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
26432                                + " procStateSeq: " + procStateSeq);
26433                    }
26434                    return;
26435                }
26436            }
26437            synchronized (record.networkStateLock) {
26438                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
26439                    if (DEBUG_NETWORK) {
26440                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
26441                                + " been handled for uid: " + uid);
26442                    }
26443                    return;
26444                }
26445                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
26446                if (record.curProcStateSeq > procStateSeq) {
26447                    if (DEBUG_NETWORK) {
26448                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
26449                                + ", curProcstateSeq: " + record.curProcStateSeq
26450                                + ", procStateSeq: " + procStateSeq);
26451                    }
26452                    return;
26453                }
26454                if (record.waitingForNetwork) {
26455                    if (DEBUG_NETWORK) {
26456                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
26457                                + ", procStateSeq: " + procStateSeq);
26458                    }
26459                    record.networkStateLock.notifyAll();
26460                }
26461            }
26462        }
26463
26464        @Override
26465        public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
26466            synchronized (ActivityManagerService.this) {
26467                mActiveVoiceInteractionServiceComponent = component;
26468            }
26469        }
26470
26471        /**
26472         * Called after virtual display Id is updated by
26473         * {@link com.android.server.vr.Vr2dDisplay} with a specific
26474         * {@param vrVr2dDisplayId}.
26475         */
26476        @Override
26477        public void setVr2dDisplayId(int vr2dDisplayId) {
26478            if (DEBUG_STACK) {
26479                Slog.d(TAG, "setVr2dDisplayId called for: " +
26480                        vr2dDisplayId);
26481            }
26482            synchronized (ActivityManagerService.this) {
26483                mVr2dDisplayId = vr2dDisplayId;
26484            }
26485        }
26486
26487        @Override
26488        public void saveANRState(String reason) {
26489            synchronized (ActivityManagerService.this) {
26490                final StringWriter sw = new StringWriter();
26491                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
26492                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
26493                if (reason != null) {
26494                    pw.println("  Reason: " + reason);
26495                }
26496                pw.println();
26497                mActivityStartController.dump(pw, "  ", null);
26498                pw.println();
26499                pw.println("-------------------------------------------------------------------------------");
26500                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
26501                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
26502                        "" /* header */);
26503                pw.println();
26504                pw.close();
26505
26506                mLastANRState = sw.toString();
26507            }
26508        }
26509
26510        @Override
26511        public void clearSavedANRState() {
26512            synchronized (ActivityManagerService.this) {
26513                mLastANRState = null;
26514            }
26515        }
26516
26517        @Override
26518        public void setFocusedActivity(IBinder token) {
26519            synchronized (ActivityManagerService.this) {
26520                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
26521                if (r == null) {
26522                    throw new IllegalArgumentException(
26523                            "setFocusedActivity: No activity record matching token=" + token);
26524                }
26525                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
26526                        r, "setFocusedActivity")) {
26527                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
26528                }
26529            }
26530        }
26531
26532        @Override
26533        public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
26534            synchronized (ActivityManagerService.this) {
26535                if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
26536                    ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
26537                    if (types == null) {
26538                        if (uid < 0) {
26539                            return;
26540                        }
26541                        types = new ArrayMap<>();
26542                        mAllowAppSwitchUids.put(userId, types);
26543                    }
26544                    if (uid < 0) {
26545                        types.remove(type);
26546                    } else {
26547                        types.put(type, uid);
26548                    }
26549                }
26550            }
26551        }
26552
26553        @Override
26554        public boolean isRuntimeRestarted() {
26555            return mSystemServiceManager.isRuntimeRestarted();
26556        }
26557
26558        @Override
26559        public boolean hasRunningActivity(int uid, @Nullable String packageName) {
26560            if (packageName == null) return false;
26561
26562            synchronized (ActivityManagerService.this) {
26563                for (int i = 0; i < mLruProcesses.size(); i++) {
26564                    final ProcessRecord processRecord = mLruProcesses.get(i);
26565                    if (processRecord.uid == uid) {
26566                        for (int j = 0; j < processRecord.activities.size(); j++) {
26567                            final ActivityRecord activityRecord = processRecord.activities.get(j);
26568                            if (packageName.equals(activityRecord.packageName)) {
26569                                return true;
26570                            }
26571                        }
26572                    }
26573                }
26574            }
26575            return false;
26576        }
26577
26578        @Override
26579        public void registerScreenObserver(ScreenObserver observer) {
26580            mScreenObservers.add(observer);
26581        }
26582
26583        @Override
26584        public boolean canStartMoreUsers() {
26585            return mUserController.canStartMoreUsers();
26586        }
26587
26588        @Override
26589        public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
26590            mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage);
26591        }
26592
26593        @Override
26594        public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
26595            mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage);
26596        }
26597
26598        @Override
26599        public int getMaxRunningUsers() {
26600            return mUserController.mMaxRunningUsers;
26601        }
26602
26603        @Override
26604        public boolean isCallerRecents(int callingUid) {
26605            return getRecentTasks().isCallerRecents(callingUid);
26606        }
26607
26608        @Override
26609        public boolean isRecentsComponentHomeActivity(int userId) {
26610            return getRecentTasks().isRecentsComponentHomeActivity(userId);
26611        }
26612
26613        @Override
26614        public boolean isUidActive(int uid) {
26615            synchronized (ActivityManagerService.this) {
26616                final UidRecord uidRec = mActiveUids.get(uid);
26617                return (uidRec != null) && !uidRec.idle;
26618            }
26619        }
26620
26621        @Override
26622        public List<ProcessMemoryState> getMemoryStateForProcesses() {
26623            List<ProcessMemoryState> processMemoryStates = new ArrayList<>();
26624            synchronized (mPidsSelfLocked) {
26625                for (int i = 0, size = mPidsSelfLocked.size(); i < size; i++) {
26626                    final ProcessRecord r = mPidsSelfLocked.valueAt(i);
26627                    final int pid = r.pid;
26628                    final int uid = r.uid;
26629                    final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
26630                    if (memoryStat == null) {
26631                        continue;
26632                    }
26633                    ProcessMemoryState processMemoryState =
26634                            new ProcessMemoryState(uid,
26635                                    r.processName,
26636                                    r.maxAdj,
26637                                    memoryStat.pgfault,
26638                                    memoryStat.pgmajfault,
26639                                    memoryStat.rssInBytes,
26640                                    memoryStat.cacheInBytes,
26641                                    memoryStat.swapInBytes);
26642                    processMemoryStates.add(processMemoryState);
26643                }
26644            }
26645            return processMemoryStates;
26646        }
26647
26648        @Override
26649        public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
26650            ActivityManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
26651        }
26652    }
26653
26654    /**
26655     * Called by app main thread to wait for the network policy rules to get updated.
26656     *
26657     * @param procStateSeq The sequence number indicating the process state change that the main
26658     *                     thread is interested in.
26659     */
26660    @Override
26661    public void waitForNetworkStateUpdate(long procStateSeq) {
26662        final int callingUid = Binder.getCallingUid();
26663        if (DEBUG_NETWORK) {
26664            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
26665        }
26666        UidRecord record;
26667        synchronized (this) {
26668            record = mActiveUids.get(callingUid);
26669            if (record == null) {
26670                return;
26671            }
26672        }
26673        synchronized (record.networkStateLock) {
26674            if (record.lastDispatchedProcStateSeq < procStateSeq) {
26675                if (DEBUG_NETWORK) {
26676                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
26677                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
26678                            + " lastProcStateSeqDispatchedToObservers: "
26679                            + record.lastDispatchedProcStateSeq);
26680                }
26681                return;
26682            }
26683            if (record.curProcStateSeq > procStateSeq) {
26684                if (DEBUG_NETWORK) {
26685                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
26686                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
26687                            + ", procStateSeq: " + procStateSeq);
26688                }
26689                return;
26690            }
26691            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
26692                if (DEBUG_NETWORK) {
26693                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
26694                            + procStateSeq + ", so no need to wait. Uid: "
26695                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
26696                            + record.lastNetworkUpdatedProcStateSeq);
26697                }
26698                return;
26699            }
26700            try {
26701                if (DEBUG_NETWORK) {
26702                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
26703                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
26704                }
26705                final long startTime = SystemClock.uptimeMillis();
26706                record.waitingForNetwork = true;
26707                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
26708                record.waitingForNetwork = false;
26709                final long totalTime = SystemClock.uptimeMillis() - startTime;
26710                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
26711                    Slog.w(TAG_NETWORK, "Total time waited for network rules to get updated: "
26712                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
26713                            + procStateSeq + " UidRec: " + record
26714                            + " validateUidRec: " + mValidateUids.get(callingUid));
26715                }
26716            } catch (InterruptedException e) {
26717                Thread.currentThread().interrupt();
26718            }
26719        }
26720    }
26721
26722    public void waitForBroadcastIdle(PrintWriter pw) {
26723        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
26724        while (true) {
26725            boolean idle = true;
26726            synchronized (this) {
26727                for (BroadcastQueue queue : mBroadcastQueues) {
26728                    if (!queue.isIdle()) {
26729                        final String msg = "Waiting for queue " + queue + " to become idle...";
26730                        pw.println(msg);
26731                        pw.flush();
26732                        Slog.v(TAG, msg);
26733                        idle = false;
26734                    }
26735                }
26736            }
26737
26738            if (idle) {
26739                final String msg = "All broadcast queues are idle!";
26740                pw.println(msg);
26741                pw.flush();
26742                Slog.v(TAG, msg);
26743                return;
26744            } else {
26745                SystemClock.sleep(1000);
26746            }
26747        }
26748    }
26749
26750    /**
26751     * Return the user id of the last resumed activity.
26752     */
26753    @Override
26754    public @UserIdInt int getLastResumedActivityUserId() {
26755        enforceCallingPermission(
26756                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
26757        synchronized (this) {
26758            if (mLastResumedActivity == null) {
26759                return mUserController.getCurrentUserId();
26760            }
26761            return mLastResumedActivity.userId;
26762        }
26763    }
26764
26765    /**
26766     * Kill processes for the user with id userId and that depend on the package named packageName
26767     */
26768    @Override
26769    public void killPackageDependents(String packageName, int userId) {
26770        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
26771        if (packageName == null) {
26772            throw new NullPointerException(
26773                    "Cannot kill the dependents of a package without its name.");
26774        }
26775
26776        long callingId = Binder.clearCallingIdentity();
26777        IPackageManager pm = AppGlobals.getPackageManager();
26778        int pkgUid = -1;
26779        try {
26780            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
26781        } catch (RemoteException e) {
26782        }
26783        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
26784            throw new IllegalArgumentException(
26785                    "Cannot kill dependents of non-existing package " + packageName);
26786        }
26787        try {
26788            synchronized(this) {
26789                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
26790                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
26791                        "dep: " + packageName);
26792            }
26793        } finally {
26794            Binder.restoreCallingIdentity(callingId);
26795        }
26796    }
26797
26798    @Override
26799    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
26800            CharSequence message) throws RemoteException {
26801        if (message != null) {
26802            enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
26803                    "dismissKeyguard()");
26804        }
26805        final long callingId = Binder.clearCallingIdentity();
26806        try {
26807            mKeyguardController.dismissKeyguard(token, callback, message);
26808        } finally {
26809            Binder.restoreCallingIdentity(callingId);
26810        }
26811    }
26812
26813    @Override
26814    public int restartUserInBackground(final int userId) {
26815        return mUserController.restartUser(userId, /* foreground */ false);
26816    }
26817
26818    @Override
26819    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
26820        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
26821                "scheduleApplicationInfoChanged()");
26822
26823        synchronized (this) {
26824            final long origId = Binder.clearCallingIdentity();
26825            try {
26826                updateApplicationInfoLocked(packageNames, userId);
26827            } finally {
26828                Binder.restoreCallingIdentity(origId);
26829            }
26830        }
26831    }
26832
26833    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
26834        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
26835        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
26836            final ProcessRecord app = mLruProcesses.get(i);
26837            if (app.thread == null) {
26838                continue;
26839            }
26840
26841            if (userId != UserHandle.USER_ALL && app.userId != userId) {
26842                continue;
26843            }
26844
26845            final int packageCount = app.pkgList.size();
26846            for (int j = 0; j < packageCount; j++) {
26847                final String packageName = app.pkgList.keyAt(j);
26848                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
26849                    try {
26850                        final ApplicationInfo ai = AppGlobals.getPackageManager()
26851                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
26852                        if (ai != null) {
26853                            app.thread.scheduleApplicationInfoChanged(ai);
26854                        }
26855                    } catch (RemoteException e) {
26856                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
26857                                    packageName, app));
26858                    }
26859                }
26860            }
26861        }
26862        if (updateFrameworkRes) {
26863            // Update system server components that need to know about changed overlays. Because the
26864            // overlay is applied in ActivityThread, we need to serialize through its thread too.
26865            final Executor executor = ActivityThread.currentActivityThread().getExecutor();
26866            final DisplayManagerInternal display =
26867                    LocalServices.getService(DisplayManagerInternal.class);
26868            if (display != null) {
26869                executor.execute(display::onOverlayChanged);
26870            }
26871            if (mWindowManager != null) {
26872                executor.execute(mWindowManager::onOverlayChanged);
26873            }
26874        }
26875    }
26876
26877    /**
26878     * Attach an agent to the specified process (proces name or PID)
26879     */
26880    public void attachAgent(String process, String path) {
26881        try {
26882            synchronized (this) {
26883                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
26884                if (proc == null || proc.thread == null) {
26885                    throw new IllegalArgumentException("Unknown process: " + process);
26886                }
26887
26888                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26889                if (!isDebuggable) {
26890                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26891                        throw new SecurityException("Process not debuggable: " + proc);
26892                    }
26893                }
26894
26895                proc.thread.attachAgent(path);
26896            }
26897        } catch (RemoteException e) {
26898            throw new IllegalStateException("Process disappeared");
26899        }
26900    }
26901
26902    @VisibleForTesting
26903    public static class Injector {
26904        private NetworkManagementInternal mNmi;
26905
26906        public Context getContext() {
26907            return null;
26908        }
26909
26910        public AppOpsService getAppOpsService(File file, Handler handler) {
26911            return new AppOpsService(file, handler);
26912        }
26913
26914        public Handler getUiHandler(ActivityManagerService service) {
26915            return service.new UiHandler();
26916        }
26917
26918        public boolean isNetworkRestrictedForUid(int uid) {
26919            if (ensureHasNetworkManagementInternal()) {
26920                return mNmi.isNetworkRestrictedForUid(uid);
26921            }
26922            return false;
26923        }
26924
26925        private boolean ensureHasNetworkManagementInternal() {
26926            if (mNmi == null) {
26927                mNmi = LocalServices.getService(NetworkManagementInternal.class);
26928            }
26929            return mNmi != null;
26930        }
26931    }
26932
26933    @Override
26934    public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
26935            throws RemoteException {
26936        synchronized (this) {
26937            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26938            if (r == null) {
26939                return;
26940            }
26941            final long origId = Binder.clearCallingIdentity();
26942            try {
26943                r.setShowWhenLocked(showWhenLocked);
26944            } finally {
26945                Binder.restoreCallingIdentity(origId);
26946            }
26947        }
26948    }
26949
26950    @Override
26951    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
26952        synchronized (this) {
26953            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26954            if (r == null) {
26955                return;
26956            }
26957            final long origId = Binder.clearCallingIdentity();
26958            try {
26959                r.setTurnScreenOn(turnScreenOn);
26960            } finally {
26961                Binder.restoreCallingIdentity(origId);
26962            }
26963        }
26964    }
26965
26966    @Override
26967    public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)
26968            throws RemoteException {
26969        enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
26970                "registerRemoteAnimations");
26971        definition.setCallingPid(Binder.getCallingPid());
26972        synchronized (this) {
26973            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26974            if (r == null) {
26975                return;
26976            }
26977            final long origId = Binder.clearCallingIdentity();
26978            try {
26979                r.registerRemoteAnimations(definition);
26980            } finally {
26981                Binder.restoreCallingIdentity(origId);
26982            }
26983        }
26984    }
26985
26986    @Override
26987    public void registerRemoteAnimationForNextActivityStart(String packageName,
26988            RemoteAnimationAdapter adapter) throws RemoteException {
26989        enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
26990                "registerRemoteAnimationForNextActivityStart");
26991        adapter.setCallingPid(Binder.getCallingPid());
26992        synchronized (this) {
26993            final long origId = Binder.clearCallingIdentity();
26994            try {
26995                mActivityStartController.registerRemoteAnimationForNextActivityStart(packageName,
26996                        adapter);
26997            } finally {
26998                Binder.restoreCallingIdentity(origId);
26999            }
27000        }
27001    }
27002
27003    /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
27004    @Override
27005    public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
27006        synchronized (this) {
27007            final long origId = Binder.clearCallingIdentity();
27008            try {
27009                mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
27010            } finally {
27011                Binder.restoreCallingIdentity(origId);
27012            }
27013        }
27014    }
27015}
27016