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_NONE;
41import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
42import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
43import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
44import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
45import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
46import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
47import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
48import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
49import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
50import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
51import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
52import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
53import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
54import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
55import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
56import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
57import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
58import static android.content.pm.PackageManager.GET_PROVIDERS;
59import static android.content.pm.PackageManager.MATCH_ANY_USER;
60import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
61import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
62import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
63import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
64import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
65import static android.content.pm.PackageManager.PERMISSION_GRANTED;
66import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
67import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
68import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
69import static android.os.Build.VERSION_CODES.N;
70import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
71import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
72import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
73import static android.os.IServiceManager.DUMP_FLAG_PROTO;
74import static android.os.Process.BLUETOOTH_UID;
75import static android.os.Process.FIRST_APPLICATION_UID;
76import static android.os.Process.FIRST_ISOLATED_UID;
77import static android.os.Process.LAST_ISOLATED_UID;
78import static android.os.Process.NFC_UID;
79import static android.os.Process.PHONE_UID;
80import static android.os.Process.PROC_CHAR;
81import static android.os.Process.PROC_OUT_LONG;
82import static android.os.Process.PROC_PARENS;
83import static android.os.Process.PROC_SPACE_TERM;
84import static android.os.Process.ProcessStartResult;
85import static android.os.Process.ROOT_UID;
86import static android.os.Process.SCHED_FIFO;
87import static android.os.Process.SCHED_OTHER;
88import static android.os.Process.SCHED_RESET_ON_FORK;
89import static android.os.Process.SE_UID;
90import static android.os.Process.SHELL_UID;
91import static android.os.Process.SIGNAL_QUIT;
92import static android.os.Process.SIGNAL_USR1;
93import static android.os.Process.SYSTEM_UID;
94import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
95import static android.os.Process.THREAD_GROUP_DEFAULT;
96import static android.os.Process.THREAD_GROUP_RESTRICTED;
97import static android.os.Process.THREAD_GROUP_TOP_APP;
98import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
99import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
100import static android.os.Process.getFreeMemory;
101import static android.os.Process.getTotalMemory;
102import static android.os.Process.isThreadInProcess;
103import static android.os.Process.killProcess;
104import static android.os.Process.killProcessQuiet;
105import static android.os.Process.myPid;
106import static android.os.Process.myUid;
107import static android.os.Process.readProcFile;
108import static android.os.Process.removeAllProcessGroups;
109import static android.os.Process.sendSignal;
110import static android.os.Process.setProcessGroup;
111import static android.os.Process.setThreadPriority;
112import static android.os.Process.setThreadScheduler;
113import static android.os.Process.startWebView;
114import static android.os.Process.zygoteProcess;
115import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
116import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
117import static android.provider.Settings.Global.DEBUG_APP;
118import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
119import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
120import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
121import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
122import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
123import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
124import static android.provider.Settings.System.FONT_SCALE;
125import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
126import static android.text.format.DateUtils.DAY_IN_MILLIS;
127import static android.view.Display.DEFAULT_DISPLAY;
128import static android.view.Display.INVALID_DISPLAY;
129import static com.android.internal.util.XmlUtils.readBooleanAttribute;
130import static com.android.internal.util.XmlUtils.readIntAttribute;
131import static com.android.internal.util.XmlUtils.readLongAttribute;
132import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
133import static com.android.internal.util.XmlUtils.writeIntAttribute;
134import static com.android.internal.util.XmlUtils.writeLongAttribute;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
141import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
142import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
143import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
144import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
145import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
146import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
147import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
148import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
149import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
150import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
151import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
152import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
153import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
154import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
155import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
156import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
157import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
158import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
159import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
160import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
161import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
162import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
163import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
164import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
165import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
166import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
167import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
168import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
169import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
170import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
171import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
172import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
173import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
174import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
175import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
176import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
177import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
178import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
179import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
180import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
181import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
182import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
183import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
184import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
185import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
186import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
187import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
188import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
189import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
190import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
191import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
192import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
193import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
194import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
195import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
196import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
197import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
198import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
199import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
200import static com.android.server.am.MemoryStatUtil.hasMemcg;
201import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
202import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
203import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
204import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
205import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
206import static android.view.WindowManager.TRANSIT_NONE;
207import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
208import static android.view.WindowManager.TRANSIT_TASK_OPEN;
209import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
210import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
211import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
212import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
213import static org.xmlpull.v1.XmlPullParser.START_TAG;
214
215import android.Manifest;
216import android.Manifest.permission;
217import android.annotation.NonNull;
218import android.annotation.Nullable;
219import android.annotation.UserIdInt;
220import android.app.Activity;
221import android.app.ActivityManager;
222import android.app.ActivityManager.RunningTaskInfo;
223import android.app.ActivityManager.StackInfo;
224import android.app.ActivityManager.TaskSnapshot;
225import android.app.ActivityManagerInternal;
226import android.app.ActivityManagerInternal.ScreenObserver;
227import android.app.ActivityManagerInternal.SleepToken;
228import android.app.ActivityManagerProto;
229import android.app.ActivityOptions;
230import android.app.ActivityThread;
231import android.app.AlertDialog;
232import android.app.AppGlobals;
233import android.app.AppOpsManager;
234import android.app.ApplicationErrorReport;
235import android.app.ApplicationThreadConstants;
236import android.app.BroadcastOptions;
237import android.app.ContentProviderHolder;
238import android.app.Dialog;
239import android.app.GrantedUriPermission;
240import android.app.IActivityController;
241import android.app.IActivityManager;
242import android.app.IApplicationThread;
243import android.app.IAssistDataReceiver;
244import android.app.IInstrumentationWatcher;
245import android.app.INotificationManager;
246import android.app.IProcessObserver;
247import android.app.IServiceConnection;
248import android.app.IStopUserCallback;
249import android.app.ITaskStackListener;
250import android.app.IUiAutomationConnection;
251import android.app.IUidObserver;
252import android.app.IUserSwitchObserver;
253import android.app.Instrumentation;
254import android.app.Notification;
255import android.app.NotificationManager;
256import android.app.PendingIntent;
257import android.app.PictureInPictureParams;
258import android.app.ProcessMemoryState;
259import android.app.ProfilerInfo;
260import android.app.RemoteAction;
261import android.app.WaitResult;
262import android.app.WindowConfiguration.ActivityType;
263import android.app.WindowConfiguration.WindowingMode;
264import android.app.admin.DevicePolicyCache;
265import android.app.assist.AssistContent;
266import android.app.assist.AssistStructure;
267import android.app.backup.IBackupManager;
268import android.app.servertransaction.ConfigurationChangeItem;
269import android.app.usage.UsageEvents;
270import android.app.usage.UsageStatsManagerInternal;
271import android.appwidget.AppWidgetManager;
272import android.content.ActivityNotFoundException;
273import android.content.BroadcastReceiver;
274import android.content.ClipData;
275import android.content.ComponentCallbacks2;
276import android.content.ComponentName;
277import android.content.ContentProvider;
278import android.content.ContentResolver;
279import android.content.Context;
280import android.content.DialogInterface;
281import android.content.IContentProvider;
282import android.content.IIntentReceiver;
283import android.content.IIntentSender;
284import android.content.Intent;
285import android.content.IntentFilter;
286import android.content.pm.ActivityInfo;
287import android.content.pm.ApplicationInfo;
288import android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy;
289import android.content.pm.ConfigurationInfo;
290import android.content.pm.IPackageDataObserver;
291import android.content.pm.IPackageManager;
292import android.content.pm.InstrumentationInfo;
293import android.content.pm.PackageInfo;
294import android.content.pm.PackageManager;
295import android.content.pm.PackageManager.NameNotFoundException;
296import android.content.pm.PackageManagerInternal;
297import android.content.pm.ParceledListSlice;
298import android.content.pm.PathPermission;
299import android.content.pm.PermissionInfo;
300import android.content.pm.ProviderInfo;
301import android.content.pm.ResolveInfo;
302import android.content.pm.SELinuxUtil;
303import android.content.pm.ServiceInfo;
304import android.content.pm.UserInfo;
305import android.content.res.CompatibilityInfo;
306import android.content.res.Configuration;
307import android.content.res.Resources;
308import android.database.ContentObserver;
309import android.graphics.Bitmap;
310import android.graphics.Point;
311import android.graphics.Rect;
312import android.hardware.display.DisplayManagerInternal;
313import android.location.LocationManager;
314import android.media.audiofx.AudioEffect;
315import android.metrics.LogMaker;
316import android.net.Proxy;
317import android.net.ProxyInfo;
318import android.net.Uri;
319import android.os.BatteryStats;
320import android.os.Binder;
321import android.os.Build;
322import android.os.Bundle;
323import android.os.Debug;
324import android.os.DropBoxManager;
325import android.os.Environment;
326import android.os.FactoryTest;
327import android.os.FileObserver;
328import android.os.FileUtils;
329import android.os.Handler;
330import android.os.IBinder;
331import android.os.IDeviceIdentifiersPolicyService;
332import android.os.IPermissionController;
333import android.os.IProcessInfoService;
334import android.os.IProgressListener;
335import android.os.LocaleList;
336import android.os.Looper;
337import android.os.Message;
338import android.os.Parcel;
339import android.os.ParcelFileDescriptor;
340import android.os.PersistableBundle;
341import android.os.PowerManager;
342import android.os.PowerManager.ServiceType;
343import android.os.PowerManagerInternal;
344import android.os.Process;
345import android.os.RemoteCallbackList;
346import android.os.RemoteException;
347import android.os.ResultReceiver;
348import android.os.ServiceManager;
349import android.os.ShellCallback;
350import android.os.StrictMode;
351import android.os.SystemClock;
352import android.os.SystemProperties;
353import android.os.Trace;
354import android.os.TransactionTooLargeException;
355import android.os.UpdateLock;
356import android.os.UserHandle;
357import android.os.UserManager;
358import android.os.WorkSource;
359import android.os.storage.IStorageManager;
360import android.os.storage.StorageManager;
361import android.os.storage.StorageManagerInternal;
362import android.provider.Downloads;
363import android.provider.Settings;
364import android.service.voice.IVoiceInteractionSession;
365import android.service.voice.VoiceInteractionManagerInternal;
366import android.telecom.TelecomManager;
367import android.text.TextUtils;
368import android.text.format.DateUtils;
369import android.text.format.Time;
370import android.text.style.SuggestionSpan;
371import android.util.ArrayMap;
372import android.util.ArraySet;
373import android.util.AtomicFile;
374import android.util.DebugUtils;
375import android.util.EventLog;
376import android.util.Log;
377import android.util.LongSparseArray;
378import android.util.Pair;
379import android.util.PrintWriterPrinter;
380import android.util.Slog;
381import android.util.SparseArray;
382import android.util.SparseIntArray;
383import android.util.StatsLog;
384import android.util.TimeUtils;
385import android.util.TimingsTraceLog;
386import android.util.Xml;
387import android.util.proto.ProtoOutputStream;
388import android.util.proto.ProtoUtils;
389import android.view.Gravity;
390import android.view.IRecentsAnimationRunner;
391import android.view.LayoutInflater;
392import android.view.RemoteAnimationAdapter;
393import android.view.RemoteAnimationDefinition;
394import android.view.View;
395import android.view.WindowManager;
396import android.view.autofill.AutofillManagerInternal;
397
398import com.android.internal.R;
399import com.android.internal.annotations.GuardedBy;
400import com.android.internal.annotations.VisibleForTesting;
401import com.android.internal.app.AssistUtils;
402import com.android.internal.app.DumpHeapActivity;
403import com.android.internal.app.IAppOpsCallback;
404import com.android.internal.app.IAppOpsService;
405import com.android.internal.app.IVoiceInteractor;
406import com.android.internal.app.ProcessMap;
407import com.android.internal.app.SystemUserHomeActivity;
408import com.android.internal.app.procstats.ProcessStats;
409import com.android.internal.logging.MetricsLogger;
410import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
411import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
412import com.android.internal.notification.SystemNotificationChannels;
413import com.android.internal.os.BackgroundThread;
414import com.android.internal.os.BatteryStatsImpl;
415import com.android.internal.os.BinderInternal;
416import com.android.internal.os.logging.MetricsLoggerWrapper;
417import com.android.internal.os.ByteTransferPipe;
418import com.android.internal.os.IResultReceiver;
419import com.android.internal.os.ProcessCpuTracker;
420import com.android.internal.os.TransferPipe;
421import com.android.internal.os.Zygote;
422import com.android.internal.policy.IKeyguardDismissCallback;
423import com.android.internal.policy.KeyguardDismissCallback;
424import com.android.internal.telephony.TelephonyIntents;
425import com.android.internal.util.ArrayUtils;
426import com.android.internal.util.DumpUtils;
427import com.android.internal.util.FastPrintWriter;
428import com.android.internal.util.FastXmlSerializer;
429import com.android.internal.util.MemInfoReader;
430import com.android.internal.util.Preconditions;
431import com.android.server.AlarmManagerInternal;
432import com.android.server.AppOpsService;
433import com.android.server.AttributeCache;
434import com.android.server.BinderCallsStatsService;
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.pm.dex.DexManager;
468import com.android.server.utils.PriorityDump;
469import com.android.server.vr.VrManagerInternal;
470import com.android.server.wm.PinnedStackWindowController;
471import com.android.server.wm.WindowManagerService;
472
473import dalvik.system.VMRuntime;
474
475import libcore.io.IoUtils;
476import libcore.util.EmptyArray;
477
478import com.google.android.collect.Lists;
479import com.google.android.collect.Maps;
480
481import org.xmlpull.v1.XmlPullParser;
482import org.xmlpull.v1.XmlPullParserException;
483import org.xmlpull.v1.XmlSerializer;
484
485import java.io.File;
486import java.io.FileDescriptor;
487import java.io.FileInputStream;
488import java.io.FileNotFoundException;
489import java.io.FileOutputStream;
490import java.io.IOException;
491import java.io.InputStreamReader;
492import java.io.PrintWriter;
493import java.io.StringWriter;
494import java.io.UnsupportedEncodingException;
495import java.lang.ref.WeakReference;
496import java.nio.charset.StandardCharsets;
497import java.text.DateFormat;
498import java.text.SimpleDateFormat;
499import java.util.ArrayList;
500import java.util.Arrays;
501import java.util.Collections;
502import java.util.Comparator;
503import java.util.Date;
504import java.util.HashMap;
505import java.util.HashSet;
506import java.util.Iterator;
507import java.util.List;
508import java.util.Locale;
509import java.util.Map;
510import java.util.Objects;
511import java.util.Set;
512import java.util.concurrent.CountDownLatch;
513import java.util.concurrent.Executor;
514import java.util.concurrent.atomic.AtomicBoolean;
515import java.util.concurrent.atomic.AtomicLong;
516
517public class ActivityManagerService extends IActivityManager.Stub
518        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
519
520    /**
521     * Priority we boost main thread and RT of top app to.
522     */
523    public static final int TOP_APP_PRIORITY_BOOST = -10;
524
525    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
526    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
527    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
528    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
529    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
530    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
531    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
532    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
533    private static final String TAG_LRU = TAG + POSTFIX_LRU;
534    private static final String TAG_MU = TAG + POSTFIX_MU;
535    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
536    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
537    private static final String TAG_POWER = TAG + POSTFIX_POWER;
538    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
539    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
540    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
541    private static final String TAG_PSS = TAG + POSTFIX_PSS;
542    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
543    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
544    private static final String TAG_STACK = TAG + POSTFIX_STACK;
545    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
546    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
547    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
548    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
549
550    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
551    // here so that while the job scheduler can depend on AMS, the other way around
552    // need not be the case.
553    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
554
555    /** Control over CPU and battery monitoring */
556    // write battery stats every 30 minutes.
557    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
558    static final boolean MONITOR_CPU_USAGE = true;
559    // don't sample cpu less than every 5 seconds.
560    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
561    // wait possibly forever for next cpu sample.
562    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
563    static final boolean MONITOR_THREAD_CPU_USAGE = false;
564
565    // The flags that are set for all calls we make to the package manager.
566    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
567
568    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
569
570    // Maximum number of receivers an app can register.
571    private static final int MAX_RECEIVERS_ALLOWED_PER_APP = 1000;
572
573    // Amount of time after a call to stopAppSwitches() during which we will
574    // prevent further untrusted switches from happening.
575    static final long APP_SWITCH_DELAY_TIME = 5*1000;
576
577    // How long we wait for a launched process to attach to the activity manager
578    // before we decide it's never going to come up for real.
579    static final int PROC_START_TIMEOUT = 10*1000;
580    // How long we wait for an attached process to publish its content providers
581    // before we decide it must be hung.
582    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
583
584    // How long we wait for a launched process to attach to the activity manager
585    // before we decide it's never going to come up for real, when the process was
586    // started with a wrapper for instrumentation (such as Valgrind) because it
587    // could take much longer than usual.
588    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
589
590    // How long we allow a receiver to run before giving up on it.
591    static final int BROADCAST_FG_TIMEOUT = 10*1000;
592    static final int BROADCAST_BG_TIMEOUT = 60*1000;
593
594    // How long we wait until we timeout on key dispatching.
595    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
596
597    // How long we wait until we timeout on key dispatching during instrumentation.
598    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
599
600    // Disable hidden API checks for the newly started instrumentation.
601    // Must be kept in sync with Am.
602    private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
603
604    // How long to wait in getAssistContextExtras for the activity and foreground services
605    // to respond with the result.
606    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
607
608    // How long top wait when going through the modern assist (which doesn't need to block
609    // on getting this result before starting to launch its UI).
610    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
611
612    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
613    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
614
615    // Maximum number of persisted Uri grants a package is allowed
616    static final int MAX_PERSISTED_URI_GRANTS = 128;
617
618    static final int MY_PID = myPid();
619
620    static final String[] EMPTY_STRING_ARRAY = new String[0];
621
622    // How many bytes to write into the dropbox log before truncating
623    static final int DROPBOX_MAX_SIZE = 192 * 1024;
624    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
625    // as one line, but close enough for now.
626    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
627
628    /** If a UID observer takes more than this long, send a WTF. */
629    private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20;
630
631    // Access modes for handleIncomingUser.
632    static final int ALLOW_NON_FULL = 0;
633    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
634    static final int ALLOW_FULL_ONLY = 2;
635
636    // Necessary ApplicationInfo flags to mark an app as persistent
637    private static final int PERSISTENT_MASK =
638            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
639
640    // Intent sent when remote bugreport collection has been completed
641    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
642            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
643
644    // Used to indicate that an app transition should be animated.
645    static final boolean ANIMATE = true;
646
647    // Determines whether to take full screen screenshots
648    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
649
650    /**
651     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
652     */
653    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
654
655    /**
656     * State indicating that there is no need for any blocking for network.
657     */
658    @VisibleForTesting
659    static final int NETWORK_STATE_NO_CHANGE = 0;
660
661    /**
662     * State indicating that the main thread needs to be informed about the network wait.
663     */
664    @VisibleForTesting
665    static final int NETWORK_STATE_BLOCK = 1;
666
667    /**
668     * State indicating that any threads waiting for network state to get updated can be unblocked.
669     */
670    @VisibleForTesting
671    static final int NETWORK_STATE_UNBLOCK = 2;
672
673    // Max character limit for a notification title. If the notification title is larger than this
674    // the notification will not be legible to the user.
675    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
676
677    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
678
679    /** All system services */
680    SystemServiceManager mSystemServiceManager;
681
682    // Wrapper around VoiceInteractionServiceManager
683    private AssistUtils mAssistUtils;
684
685    // Keeps track of the active voice interaction service component, notified from
686    // VoiceInteractionManagerService
687    ComponentName mActiveVoiceInteractionServiceComponent;
688
689    private Installer mInstaller;
690
691    /** Run all ActivityStacks through this */
692    final ActivityStackSupervisor mStackSupervisor;
693    private final KeyguardController mKeyguardController;
694
695    private final ActivityStartController mActivityStartController;
696
697    private final ClientLifecycleManager mLifecycleManager;
698
699    final TaskChangeNotificationController mTaskChangeNotificationController;
700
701    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
702
703    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
704
705    public final IntentFirewall mIntentFirewall;
706
707    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
708    // default action automatically.  Important for devices without direct input
709    // devices.
710    private boolean mShowDialogs = true;
711
712    private final VrController mVrController;
713
714    // VR Vr2d Display Id.
715    int mVr2dDisplayId = INVALID_DISPLAY;
716
717    // Whether we should use SCHED_FIFO for UI and RenderThreads.
718    private boolean mUseFifoUiScheduling = false;
719
720    private static final String SYSUI_COMPONENT_NAME = "com.android.systemui/.SystemUIService";
721
722    BroadcastQueue mFgBroadcastQueue;
723    BroadcastQueue mBgBroadcastQueue;
724    // Convenient for easy iteration over the queues. Foreground is first
725    // so that dispatch of foreground broadcasts gets precedence.
726    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
727
728    BroadcastStats mLastBroadcastStats;
729    BroadcastStats mCurBroadcastStats;
730
731    BroadcastQueue broadcastQueueForIntent(Intent intent) {
732        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
733        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
734                "Broadcast intent " + intent + " on "
735                + (isFg ? "foreground" : "background") + " queue");
736        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
737    }
738
739    /**
740     * The last resumed activity. This is identical to the current resumed activity most
741     * of the time but could be different when we're pausing one activity before we resume
742     * another activity.
743     */
744    private ActivityRecord mLastResumedActivity;
745
746    /**
747     * The activity that is currently being traced as the active resumed activity.
748     *
749     * @see #updateResumedAppTrace
750     */
751    private @Nullable ActivityRecord mTracedResumedActivity;
752
753    /**
754     * If non-null, we are tracking the time the user spends in the currently focused app.
755     */
756    private AppTimeTracker mCurAppTimeTracker;
757
758    /**
759     * List of intents that were used to start the most recent tasks.
760     */
761    private final RecentTasks mRecentTasks;
762
763    /**
764     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
765     */
766    String mDeviceOwnerName;
767
768    /**
769     * The controller for all operations related to locktask.
770     */
771    private final LockTaskController mLockTaskController;
772
773    final UserController mUserController;
774
775    /**
776     * Packages that are being allowed to perform unrestricted app switches.  Mapping is
777     * User -> Type -> uid.
778     */
779    final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
780
781    final AppErrors mAppErrors;
782
783    final AppWarnings mAppWarnings;
784
785    /**
786     * Dump of the activity state at the time of the last ANR. Cleared after
787     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
788     */
789    String mLastANRState;
790
791    /**
792     * Indicates the maximum time spent waiting for the network rules to get updated.
793     */
794    @VisibleForTesting
795    long mWaitForNetworkTimeoutMs;
796
797    /** Total # of UID change events dispatched, shown in dumpsys. */
798    int mUidChangeDispatchCount;
799
800    /**
801     * Helper class which strips out priority and proto arguments then calls the dump function with
802     * the appropriate arguments. If priority arguments are omitted, function calls the legacy
803     * dump command.
804     * If priority arguments are omitted all sections are dumped, otherwise sections are dumped
805     * according to their priority.
806     */
807    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
808        @Override
809        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
810                boolean asProto) {
811            if (asProto) return;
812            doDump(fd, pw, new String[]{"activities"}, asProto);
813            doDump(fd, pw, new String[]{"service", SYSUI_COMPONENT_NAME}, asProto);
814        }
815
816        @Override
817        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
818            doDump(fd, pw, new String[]{"-a", "--normal-priority"}, asProto);
819        }
820
821        @Override
822        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
823            doDump(fd, pw, args, asProto);
824        }
825    };
826
827    public boolean canShowErrorDialogs() {
828        return mShowDialogs && !mSleeping && !mShuttingDown
829                && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
830                && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
831                        mUserController.getCurrentUserId())
832                && !(UserManager.isDeviceInDemoMode(mContext)
833                        && mUserController.getCurrentUser().isDemo());
834    }
835
836    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
837            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
838
839    static void boostPriorityForLockedSection() {
840        sThreadPriorityBooster.boost();
841    }
842
843    static void resetPriorityAfterLockedSection() {
844        sThreadPriorityBooster.reset();
845    }
846
847    public class PendingAssistExtras extends Binder implements Runnable {
848        public final ActivityRecord activity;
849        public boolean isHome;
850        public final Bundle extras;
851        public final Intent intent;
852        public final String hint;
853        public final IAssistDataReceiver receiver;
854        public final int userHandle;
855        public boolean haveResult = false;
856        public Bundle result = null;
857        public AssistStructure structure = null;
858        public AssistContent content = null;
859        public Bundle receiverExtras;
860
861        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
862                String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
863                int _userHandle) {
864            activity = _activity;
865            extras = _extras;
866            intent = _intent;
867            hint = _hint;
868            receiver = _receiver;
869            receiverExtras = _receiverExtras;
870            userHandle = _userHandle;
871        }
872
873        @Override
874        public void run() {
875            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
876            synchronized (this) {
877                haveResult = true;
878                notifyAll();
879            }
880            pendingAssistExtrasTimedOut(this);
881        }
882    }
883
884    final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
885
886    /**
887     * Process management.
888     */
889    final ProcessList mProcessList = new ProcessList();
890
891    /**
892     * All of the applications we currently have running organized by name.
893     * The keys are strings of the application package name (as
894     * returned by the package manager), and the keys are ApplicationRecord
895     * objects.
896     */
897    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
898
899    /**
900     * Tracking long-term execution of processes to look for abuse and other
901     * bad app behavior.
902     */
903    final ProcessStatsService mProcessStats;
904
905    /**
906     * The currently running isolated processes.
907     */
908    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
909
910    /**
911     * Counter for assigning isolated process uids, to avoid frequently reusing the
912     * same ones.
913     */
914    int mNextIsolatedProcessUid = 0;
915
916    /**
917     * The currently running heavy-weight process, if any.
918     */
919    ProcessRecord mHeavyWeightProcess = null;
920
921    /**
922     * Non-persistent appId whitelist for background restrictions
923     */
924    int[] mBackgroundAppIdWhitelist = new int[] {
925            BLUETOOTH_UID
926    };
927
928    /**
929     * Broadcast actions that will always be deliverable to unlaunched/background apps
930     */
931    ArraySet<String> mBackgroundLaunchBroadcasts;
932
933    /**
934     * All of the processes we currently have running organized by pid.
935     * The keys are the pid running the application.
936     *
937     * <p>NOTE: This object is protected by its own lock, NOT the global
938     * activity manager lock!
939     */
940    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
941
942    /**
943     * All of the processes that have been forced to be important.  The key
944     * is the pid of the caller who requested it (we hold a death
945     * link on it).
946     */
947    abstract class ImportanceToken implements IBinder.DeathRecipient {
948        final int pid;
949        final IBinder token;
950        final String reason;
951
952        ImportanceToken(int _pid, IBinder _token, String _reason) {
953            pid = _pid;
954            token = _token;
955            reason = _reason;
956        }
957
958        @Override
959        public String toString() {
960            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
961                    + " " + reason + " " + pid + " " + token + " }";
962        }
963
964        void writeToProto(ProtoOutputStream proto, long fieldId) {
965            final long pToken = proto.start(fieldId);
966            proto.write(ImportanceTokenProto.PID, pid);
967            if (token != null) {
968                proto.write(ImportanceTokenProto.TOKEN, token.toString());
969            }
970            proto.write(ImportanceTokenProto.REASON, reason);
971            proto.end(pToken);
972        }
973    }
974    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
975
976    /**
977     * List of records for processes that someone had tried to start before the
978     * system was ready.  We don't start them at that point, but ensure they
979     * are started by the time booting is complete.
980     */
981    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
982
983    /**
984     * List of persistent applications that are in the process
985     * of being started.
986     */
987    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
988
989    /**
990     * Processes that are being forcibly torn down.
991     */
992    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
993
994    /**
995     * List of running applications, sorted by recent usage.
996     * The first entry in the list is the least recently used.
997     */
998    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
999
1000    /**
1001     * Where in mLruProcesses that the processes hosting activities start.
1002     */
1003    int mLruProcessActivityStart = 0;
1004
1005    /**
1006     * Where in mLruProcesses that the processes hosting services start.
1007     * This is after (lower index) than mLruProcessesActivityStart.
1008     */
1009    int mLruProcessServiceStart = 0;
1010
1011    /**
1012     * List of processes that should gc as soon as things are idle.
1013     */
1014    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
1015
1016    /**
1017     * Processes we want to collect PSS data from.
1018     */
1019    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
1020
1021    private boolean mBinderTransactionTrackingEnabled = false;
1022
1023    /**
1024     * Last time we requested PSS data of all processes.
1025     */
1026    long mLastFullPssTime = SystemClock.uptimeMillis();
1027
1028    /**
1029     * If set, the next time we collect PSS data we should do a full collection
1030     * with data from native processes and the kernel.
1031     */
1032    boolean mFullPssPending = false;
1033
1034    /**
1035     * This is the process holding what we currently consider to be
1036     * the "home" activity.
1037     */
1038    ProcessRecord mHomeProcess;
1039
1040    /**
1041     * This is the process holding the activity the user last visited that
1042     * is in a different process from the one they are currently in.
1043     */
1044    ProcessRecord mPreviousProcess;
1045
1046    /**
1047     * The time at which the previous process was last visible.
1048     */
1049    long mPreviousProcessVisibleTime;
1050
1051    /**
1052     * Track all uids that have actively running processes.
1053     */
1054    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
1055
1056    /**
1057     * This is for verifying the UID report flow.
1058     */
1059    static final boolean VALIDATE_UID_STATES = true;
1060    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
1061
1062    /**
1063     * Packages that the user has asked to have run in screen size
1064     * compatibility mode instead of filling the screen.
1065     */
1066    final CompatModePackages mCompatModePackages;
1067
1068    /**
1069     * Set of IntentSenderRecord objects that are currently active.
1070     */
1071    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1072            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1073
1074    /**
1075     * Fingerprints (hashCode()) of stack traces that we've
1076     * already logged DropBox entries for.  Guarded by itself.  If
1077     * something (rogue user app) forces this over
1078     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1079     */
1080    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1081    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1082
1083    /**
1084     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1085     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1086     */
1087    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1088
1089    /**
1090     * Resolver for broadcast intents to registered receivers.
1091     * Holds BroadcastFilter (subclass of IntentFilter).
1092     */
1093    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1094            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1095        @Override
1096        protected boolean allowFilterResult(
1097                BroadcastFilter filter, List<BroadcastFilter> dest) {
1098            IBinder target = filter.receiverList.receiver.asBinder();
1099            for (int i = dest.size() - 1; i >= 0; i--) {
1100                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1101                    return false;
1102                }
1103            }
1104            return true;
1105        }
1106
1107        @Override
1108        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1109            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1110                    || userId == filter.owningUserId) {
1111                return super.newResult(filter, match, userId);
1112            }
1113            return null;
1114        }
1115
1116        @Override
1117        protected BroadcastFilter[] newArray(int size) {
1118            return new BroadcastFilter[size];
1119        }
1120
1121        @Override
1122        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1123            return packageName.equals(filter.packageName);
1124        }
1125    };
1126
1127    /**
1128     * State of all active sticky broadcasts per user.  Keys are the action of the
1129     * sticky Intent, values are an ArrayList of all broadcasted intents with
1130     * that action (which should usually be one).  The SparseArray is keyed
1131     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1132     * for stickies that are sent to all users.
1133     */
1134    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1135            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1136
1137    final ActiveServices mServices;
1138
1139    final static class Association {
1140        final int mSourceUid;
1141        final String mSourceProcess;
1142        final int mTargetUid;
1143        final ComponentName mTargetComponent;
1144        final String mTargetProcess;
1145
1146        int mCount;
1147        long mTime;
1148
1149        int mNesting;
1150        long mStartTime;
1151
1152        // states of the source process when the bind occurred.
1153        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1154        long mLastStateUptime;
1155        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1156                - ActivityManager.MIN_PROCESS_STATE+1];
1157
1158        Association(int sourceUid, String sourceProcess, int targetUid,
1159                ComponentName targetComponent, String targetProcess) {
1160            mSourceUid = sourceUid;
1161            mSourceProcess = sourceProcess;
1162            mTargetUid = targetUid;
1163            mTargetComponent = targetComponent;
1164            mTargetProcess = targetProcess;
1165        }
1166    }
1167
1168    /**
1169     * When service association tracking is enabled, this is all of the associations we
1170     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1171     * -> association data.
1172     */
1173    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1174            mAssociations = new SparseArray<>();
1175    boolean mTrackingAssociations;
1176
1177    /**
1178     * Backup/restore process management
1179     */
1180    String mBackupAppName = null;
1181    BackupRecord mBackupTarget = null;
1182
1183    final ProviderMap mProviderMap;
1184
1185    /**
1186     * List of content providers who have clients waiting for them.  The
1187     * application is currently being launched and the provider will be
1188     * removed from this list once it is published.
1189     */
1190    final ArrayList<ContentProviderRecord> mLaunchingProviders
1191            = new ArrayList<ContentProviderRecord>();
1192
1193    /**
1194     * File storing persisted {@link #mGrantedUriPermissions}.
1195     */
1196    private final AtomicFile mGrantFile;
1197
1198    /** XML constants used in {@link #mGrantFile} */
1199    private static final String TAG_URI_GRANTS = "uri-grants";
1200    private static final String TAG_URI_GRANT = "uri-grant";
1201    private static final String ATTR_USER_HANDLE = "userHandle";
1202    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1203    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1204    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1205    private static final String ATTR_TARGET_PKG = "targetPkg";
1206    private static final String ATTR_URI = "uri";
1207    private static final String ATTR_MODE_FLAGS = "modeFlags";
1208    private static final String ATTR_CREATED_TIME = "createdTime";
1209    private static final String ATTR_PREFIX = "prefix";
1210
1211    /**
1212     * Global set of specific {@link Uri} permissions that have been granted.
1213     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1214     * to {@link UriPermission#uri} to {@link UriPermission}.
1215     */
1216    @GuardedBy("this")
1217    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1218            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1219
1220    public static class GrantUri {
1221        public final int sourceUserId;
1222        public final Uri uri;
1223        public boolean prefix;
1224
1225        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1226            this.sourceUserId = sourceUserId;
1227            this.uri = uri;
1228            this.prefix = prefix;
1229        }
1230
1231        @Override
1232        public int hashCode() {
1233            int hashCode = 1;
1234            hashCode = 31 * hashCode + sourceUserId;
1235            hashCode = 31 * hashCode + uri.hashCode();
1236            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1237            return hashCode;
1238        }
1239
1240        @Override
1241        public boolean equals(Object o) {
1242            if (o instanceof GrantUri) {
1243                GrantUri other = (GrantUri) o;
1244                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1245                        && prefix == other.prefix;
1246            }
1247            return false;
1248        }
1249
1250        @Override
1251        public String toString() {
1252            String result = uri.toString() + " [user " + sourceUserId + "]";
1253            if (prefix) result += " [prefix]";
1254            return result;
1255        }
1256
1257        public String toSafeString() {
1258            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1259            if (prefix) result += " [prefix]";
1260            return result;
1261        }
1262
1263        public void writeToProto(ProtoOutputStream proto, long fieldId) {
1264            long token = proto.start(fieldId);
1265            proto.write(GrantUriProto.URI, uri.toString());
1266            proto.write(GrantUriProto.SOURCE_USER_ID, sourceUserId);
1267            proto.end(token);
1268        }
1269
1270        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1271            if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
1272                return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1273                        ContentProvider.getUriWithoutUserId(uri), false);
1274            } else {
1275                return new GrantUri(defaultSourceUserHandle, uri, false);
1276            }
1277        }
1278    }
1279
1280    boolean mSystemProvidersInstalled;
1281
1282    CoreSettingsObserver mCoreSettingsObserver;
1283
1284    FontScaleSettingObserver mFontScaleSettingObserver;
1285
1286    private final class FontScaleSettingObserver extends ContentObserver {
1287        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1288        private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
1289
1290        public FontScaleSettingObserver() {
1291            super(mHandler);
1292            ContentResolver resolver = mContext.getContentResolver();
1293            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1294            resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
1295                    UserHandle.USER_ALL);
1296        }
1297
1298        @Override
1299        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1300            if (mFontScaleUri.equals(uri)) {
1301                updateFontScaleIfNeeded(userId);
1302            } else if (mHideErrorDialogsUri.equals(uri)) {
1303                synchronized (ActivityManagerService.this) {
1304                    updateShouldShowDialogsLocked(getGlobalConfiguration());
1305                }
1306            }
1307        }
1308    }
1309
1310    DevelopmentSettingsObserver mDevelopmentSettingsObserver;
1311
1312    private final class DevelopmentSettingsObserver extends ContentObserver {
1313        private final Uri mUri = Settings.Global
1314                .getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
1315
1316        private final ComponentName mBugreportStorageProvider = new ComponentName(
1317                "com.android.shell", "com.android.shell.BugreportStorageProvider");
1318
1319        public DevelopmentSettingsObserver() {
1320            super(mHandler);
1321            mContext.getContentResolver().registerContentObserver(mUri, false, this,
1322                    UserHandle.USER_ALL);
1323            // Always kick once to ensure that we match current state
1324            onChange();
1325        }
1326
1327        @Override
1328        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1329            if (mUri.equals(uri)) {
1330                onChange();
1331            }
1332        }
1333
1334        public void onChange() {
1335            final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
1336                    Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, Build.IS_ENG ? 1 : 0) != 0;
1337            mContext.getPackageManager().setComponentEnabledSetting(mBugreportStorageProvider,
1338                    enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1339                            : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
1340                    0);
1341        }
1342    }
1343
1344    /**
1345     * Thread-local storage used to carry caller permissions over through
1346     * indirect content-provider access.
1347     */
1348    private class Identity {
1349        public final IBinder token;
1350        public final int pid;
1351        public final int uid;
1352
1353        Identity(IBinder _token, int _pid, int _uid) {
1354            token = _token;
1355            pid = _pid;
1356            uid = _uid;
1357        }
1358    }
1359
1360    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1361
1362    /**
1363     * All information we have collected about the runtime performance of
1364     * any user id that can impact battery performance.
1365     */
1366    final BatteryStatsService mBatteryStatsService;
1367
1368    /**
1369     * Information about component usage
1370     */
1371    UsageStatsManagerInternal mUsageStatsService;
1372
1373    /**
1374     * Access to DeviceIdleController service.
1375     */
1376    DeviceIdleController.LocalService mLocalDeviceIdleController;
1377
1378    /**
1379     * Power-save whitelisted app-ids (not including except-idle-whitelisted ones).
1380     */
1381    int[] mDeviceIdleWhitelist = new int[0];
1382
1383    /**
1384     * Power-save whitelisted app-ids (including except-idle-whitelisted ones).
1385     */
1386    int[] mDeviceIdleExceptIdleWhitelist = new int[0];
1387
1388    /**
1389     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1390     */
1391    int[] mDeviceIdleTempWhitelist = new int[0];
1392
1393    static final class PendingTempWhitelist {
1394        final int targetUid;
1395        final long duration;
1396        final String tag;
1397
1398        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1399            targetUid = _targetUid;
1400            duration = _duration;
1401            tag = _tag;
1402        }
1403
1404        void writeToProto(ProtoOutputStream proto, long fieldId) {
1405            final long token = proto.start(fieldId);
1406            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
1407            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
1408            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TAG, tag);
1409            proto.end(token);
1410        }
1411    }
1412
1413    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1414
1415    /**
1416     * Information about and control over application operations
1417     */
1418    final AppOpsService mAppOpsService;
1419
1420    /** Current sequencing integer of the configuration, for skipping old configurations. */
1421    private int mConfigurationSeq;
1422
1423    /**
1424     * Temp object used when global and/or display override configuration is updated. It is also
1425     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1426     * anyone...
1427     */
1428    private Configuration mTempConfig = new Configuration();
1429
1430    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1431            new UpdateConfigurationResult();
1432    private static final class UpdateConfigurationResult {
1433        // Configuration changes that were updated.
1434        int changes;
1435        // If the activity was relaunched to match the new configuration.
1436        boolean activityRelaunched;
1437
1438        void reset() {
1439            changes = 0;
1440            activityRelaunched = false;
1441        }
1442    }
1443
1444    boolean mSuppressResizeConfigChanges;
1445
1446    /**
1447     * Hardware-reported OpenGLES version.
1448     */
1449    final int GL_ES_VERSION;
1450
1451    /**
1452     * List of initialization arguments to pass to all processes when binding applications to them.
1453     * For example, references to the commonly used services.
1454     */
1455    ArrayMap<String, IBinder> mAppBindArgs;
1456    ArrayMap<String, IBinder> mIsolatedAppBindArgs;
1457
1458    /**
1459     * Temporary to avoid allocations.  Protected by main lock.
1460     */
1461    final StringBuilder mStringBuilder = new StringBuilder(256);
1462
1463    /**
1464     * Used to control how we initialize the service.
1465     */
1466    ComponentName mTopComponent;
1467    String mTopAction = Intent.ACTION_MAIN;
1468    String mTopData;
1469
1470    volatile boolean mProcessesReady = false;
1471    volatile boolean mSystemReady = false;
1472    volatile boolean mOnBattery = false;
1473    volatile int mFactoryTest;
1474
1475    @GuardedBy("this") boolean mBooting = false;
1476    @GuardedBy("this") boolean mCallFinishBooting = false;
1477    @GuardedBy("this") boolean mBootAnimationComplete = false;
1478    @GuardedBy("this") boolean mLaunchWarningShown = false;
1479    private @GuardedBy("this") boolean mCheckedForSetup = false;
1480
1481    final Context mContext;
1482
1483    /**
1484     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1485     * change at runtime. Use mContext for non-UI purposes.
1486     */
1487    final Context mUiContext;
1488
1489    /**
1490     * The time at which we will allow normal application switches again,
1491     * after a call to {@link #stopAppSwitches()}.
1492     */
1493    long mAppSwitchesAllowedTime;
1494
1495    /**
1496     * This is set to true after the first switch after mAppSwitchesAllowedTime
1497     * is set; any switches after that will clear the time.
1498     */
1499    boolean mDidAppSwitch;
1500
1501    /**
1502     * Last time (in uptime) at which we checked for power usage.
1503     */
1504    long mLastPowerCheckUptime;
1505
1506    /**
1507     * Set while we are wanting to sleep, to prevent any
1508     * activities from being started/resumed.
1509     *
1510     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1511     *
1512     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1513     * while in the sleep state until there is a pending transition out of sleep, in which case
1514     * mSleeping is set to false, and remains false while awake.
1515     *
1516     * Whether mSleeping can quickly toggled between true/false without the device actually
1517     * display changing states is undefined.
1518     */
1519    private boolean mSleeping = false;
1520
1521    /**
1522     * The process state used for processes that are running the top activities.
1523     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1524     */
1525    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1526
1527    /**
1528     * Set while we are running a voice interaction.  This overrides
1529     * sleeping while it is active.
1530     */
1531    IVoiceInteractionSession mRunningVoice;
1532
1533    /**
1534     * For some direct access we need to power manager.
1535     */
1536    PowerManagerInternal mLocalPowerManager;
1537
1538    /**
1539     * We want to hold a wake lock while running a voice interaction session, since
1540     * this may happen with the screen off and we need to keep the CPU running to
1541     * be able to continue to interact with the user.
1542     */
1543    PowerManager.WakeLock mVoiceWakeLock;
1544
1545    /**
1546     * State of external calls telling us if the device is awake or asleep.
1547     */
1548    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1549
1550    /**
1551     * State of external calls telling us if the device is awake or asleep.
1552     */
1553    private boolean mKeyguardShown = false;
1554
1555    /**
1556     * Set if we are shutting down the system, similar to sleeping.
1557     */
1558    boolean mShuttingDown = false;
1559
1560    /**
1561     * Current sequence id for oom_adj computation traversal.
1562     */
1563    int mAdjSeq = 0;
1564
1565    /**
1566     * Current sequence id for process LRU updating.
1567     */
1568    int mLruSeq = 0;
1569
1570    /**
1571     * Keep track of the non-cached/empty process we last found, to help
1572     * determine how to distribute cached/empty processes next time.
1573     */
1574    int mNumNonCachedProcs = 0;
1575
1576    /**
1577     * Keep track of the number of cached hidden procs, to balance oom adj
1578     * distribution between those and empty procs.
1579     */
1580    int mNumCachedHiddenProcs = 0;
1581
1582    /**
1583     * Keep track of the number of service processes we last found, to
1584     * determine on the next iteration which should be B services.
1585     */
1586    int mNumServiceProcs = 0;
1587    int mNewNumAServiceProcs = 0;
1588    int mNewNumServiceProcs = 0;
1589
1590    /**
1591     * Allow the current computed overall memory level of the system to go down?
1592     * This is set to false when we are killing processes for reasons other than
1593     * memory management, so that the now smaller process list will not be taken as
1594     * an indication that memory is tighter.
1595     */
1596    boolean mAllowLowerMemLevel = false;
1597
1598    /**
1599     * The last computed memory level, for holding when we are in a state that
1600     * processes are going away for other reasons.
1601     */
1602    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1603
1604    /**
1605     * The last total number of process we have, to determine if changes actually look
1606     * like a shrinking number of process due to lower RAM.
1607     */
1608    int mLastNumProcesses;
1609
1610    /**
1611     * The uptime of the last time we performed idle maintenance.
1612     */
1613    long mLastIdleTime = SystemClock.uptimeMillis();
1614
1615    /**
1616     * Total time spent with RAM that has been added in the past since the last idle time.
1617     */
1618    long mLowRamTimeSinceLastIdle = 0;
1619
1620    /**
1621     * If RAM is currently low, when that horrible situation started.
1622     */
1623    long mLowRamStartTime = 0;
1624
1625    /**
1626     * For reporting to battery stats the current top application.
1627     */
1628    private String mCurResumedPackage = null;
1629    private int mCurResumedUid = -1;
1630
1631    /**
1632     * For reporting to battery stats the apps currently running foreground
1633     * service.  The ProcessMap is package/uid tuples; each of these contain
1634     * an array of the currently foreground processes.
1635     */
1636    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1637            = new ProcessMap<ArrayList<ProcessRecord>>();
1638
1639    /**
1640     * Set if the systemServer made a call to enterSafeMode.
1641     */
1642    boolean mSafeMode;
1643
1644    /**
1645     * If true, we are running under a test environment so will sample PSS from processes
1646     * much more rapidly to try to collect better data when the tests are rapidly
1647     * running through apps.
1648     */
1649    boolean mTestPssMode = false;
1650
1651    String mDebugApp = null;
1652    boolean mWaitForDebugger = false;
1653    boolean mDebugTransient = false;
1654    String mOrigDebugApp = null;
1655    boolean mOrigWaitForDebugger = false;
1656    boolean mAlwaysFinishActivities = false;
1657    boolean mForceResizableActivities;
1658    /**
1659     * Flag that indicates if multi-window is enabled.
1660     *
1661     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1662     * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1663     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1664     * At least one of the forms of multi-window must be enabled in order for this flag to be
1665     * initialized to 'true'.
1666     *
1667     * @see #mSupportsSplitScreenMultiWindow
1668     * @see #mSupportsFreeformWindowManagement
1669     * @see #mSupportsPictureInPicture
1670     * @see #mSupportsMultiDisplay
1671     */
1672    boolean mSupportsMultiWindow;
1673    boolean mSupportsSplitScreenMultiWindow;
1674    boolean mSupportsFreeformWindowManagement;
1675    boolean mSupportsPictureInPicture;
1676    boolean mSupportsMultiDisplay;
1677    boolean mSupportsLeanbackOnly;
1678    IActivityController mController = null;
1679    boolean mControllerIsAMonkey = false;
1680    String mProfileApp = null;
1681    ProcessRecord mProfileProc = null;
1682    ProfilerInfo mProfilerInfo = null;
1683
1684    /**
1685     * Stores a map of process name -> agent string. When a process is started and mAgentAppMap
1686     * is not null, this map is checked and the mapped agent installed during bind-time. Note:
1687     * A non-null agent in mProfileInfo overrides this.
1688     */
1689    private @Nullable Map<String, String> mAppAgentMap = null;
1690
1691    int mProfileType = 0;
1692    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1693    String mMemWatchDumpProcName;
1694    String mMemWatchDumpFile;
1695    int mMemWatchDumpPid;
1696    int mMemWatchDumpUid;
1697    String mTrackAllocationApp = null;
1698    String mNativeDebuggingApp = null;
1699
1700    final long[] mTmpLong = new long[3];
1701
1702    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1703
1704    /**
1705     * A global counter for generating sequence numbers.
1706     * This value will be used when incrementing sequence numbers in individual uidRecords.
1707     *
1708     * Having a global counter ensures that seq numbers are monotonically increasing for a
1709     * particular uid even when the uidRecord is re-created.
1710     */
1711    @GuardedBy("this")
1712    @VisibleForTesting
1713    long mProcStateSeqCounter = 0;
1714
1715    /**
1716     * A global counter for generating sequence numbers to uniquely identify pending process starts.
1717     */
1718    @GuardedBy("this")
1719    private long mProcStartSeqCounter = 0;
1720
1721    /**
1722     * Contains {@link ProcessRecord} objects for pending process starts.
1723     *
1724     * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
1725     */
1726    @GuardedBy("this")
1727    private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
1728
1729    private final Injector mInjector;
1730
1731    static final class ProcessChangeItem {
1732        static final int CHANGE_ACTIVITIES = 1<<0;
1733        int changes;
1734        int uid;
1735        int pid;
1736        int processState;
1737        boolean foregroundActivities;
1738    }
1739
1740    static final class UidObserverRegistration {
1741        final int uid;
1742        final String pkg;
1743        final int which;
1744        final int cutpoint;
1745
1746        /**
1747         * Total # of callback calls that took more than {@link #SLOW_UID_OBSERVER_THRESHOLD_MS}.
1748         * We show it in dumpsys.
1749         */
1750        int mSlowDispatchCount;
1751
1752        /** Max time it took for each dispatch. */
1753        int mMaxDispatchTime;
1754
1755        final SparseIntArray lastProcStates;
1756
1757        // Please keep the enum lists in sync
1758        private static int[] ORIG_ENUMS = new int[]{
1759                ActivityManager.UID_OBSERVER_IDLE,
1760                ActivityManager.UID_OBSERVER_ACTIVE,
1761                ActivityManager.UID_OBSERVER_GONE,
1762                ActivityManager.UID_OBSERVER_PROCSTATE,
1763        };
1764        private static int[] PROTO_ENUMS = new int[]{
1765                ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
1766                ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
1767                ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
1768                ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
1769        };
1770
1771        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1772            uid = _uid;
1773            pkg = _pkg;
1774            which = _which;
1775            cutpoint = _cutpoint;
1776            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1777                lastProcStates = new SparseIntArray();
1778            } else {
1779                lastProcStates = null;
1780            }
1781        }
1782
1783        void writeToProto(ProtoOutputStream proto, long fieldId) {
1784            final long token = proto.start(fieldId);
1785            proto.write(UidObserverRegistrationProto.UID, uid);
1786            proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
1787            ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
1788                    which, ORIG_ENUMS, PROTO_ENUMS);
1789            proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
1790            if (lastProcStates != null) {
1791                final int NI = lastProcStates.size();
1792                for (int i=0; i<NI; i++) {
1793                    final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
1794                    proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i));
1795                    proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i));
1796                    proto.end(pToken);
1797                }
1798            }
1799            proto.end(token);
1800        }
1801    }
1802
1803    final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1804
1805    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1806    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1807
1808    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1809    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1810
1811    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1812    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1813
1814    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1815    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1816
1817    OomAdjObserver mCurOomAdjObserver;
1818    int mCurOomAdjUid;
1819
1820    interface OomAdjObserver {
1821        void onOomAdjMessage(String msg);
1822    }
1823
1824    /**
1825     * Runtime CPU use collection thread.  This object's lock is used to
1826     * perform synchronization with the thread (notifying it to run).
1827     */
1828    final Thread mProcessCpuThread;
1829
1830    /**
1831     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1832     * Must acquire this object's lock when accessing it.
1833     * NOTE: this lock will be held while doing long operations (trawling
1834     * through all processes in /proc), so it should never be acquired by
1835     * any critical paths such as when holding the main activity manager lock.
1836     */
1837    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1838            MONITOR_THREAD_CPU_USAGE);
1839    final AtomicLong mLastCpuTime = new AtomicLong(0);
1840    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1841    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1842
1843    long mLastWriteTime = 0;
1844
1845    /**
1846     * Used to retain an update lock when the foreground activity is in
1847     * immersive mode.
1848     */
1849    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1850
1851    /**
1852     * Set to true after the system has finished booting.
1853     */
1854    boolean mBooted = false;
1855
1856    /**
1857     * Current boot phase.
1858     */
1859    int mBootPhase;
1860
1861    WindowManagerService mWindowManager;
1862    final ActivityThread mSystemThread;
1863
1864    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1865        final ProcessRecord mApp;
1866        final int mPid;
1867        final IApplicationThread mAppThread;
1868
1869        AppDeathRecipient(ProcessRecord app, int pid,
1870                IApplicationThread thread) {
1871            if (DEBUG_ALL) Slog.v(
1872                TAG, "New death recipient " + this
1873                + " for thread " + thread.asBinder());
1874            mApp = app;
1875            mPid = pid;
1876            mAppThread = thread;
1877        }
1878
1879        @Override
1880        public void binderDied() {
1881            if (DEBUG_ALL) Slog.v(
1882                TAG, "Death received in " + this
1883                + " for thread " + mAppThread.asBinder());
1884            synchronized(ActivityManagerService.this) {
1885                appDiedLocked(mApp, mPid, mAppThread, true);
1886            }
1887        }
1888    }
1889
1890    static final int SHOW_ERROR_UI_MSG = 1;
1891    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1892    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1893    static final int UPDATE_CONFIGURATION_MSG = 4;
1894    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1895    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1896    static final int SERVICE_TIMEOUT_MSG = 12;
1897    static final int UPDATE_TIME_ZONE = 13;
1898    static final int SHOW_UID_ERROR_UI_MSG = 14;
1899    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1900    static final int PROC_START_TIMEOUT_MSG = 20;
1901    static final int KILL_APPLICATION_MSG = 22;
1902    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1903    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1904    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1905    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1906    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1907    static final int CLEAR_DNS_CACHE_MSG = 28;
1908    static final int UPDATE_HTTP_PROXY_MSG = 29;
1909    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1910    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1911    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1912    static final int REPORT_MEM_USAGE_MSG = 33;
1913    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1914    static final int PERSIST_URI_GRANTS_MSG = 38;
1915    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1916    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1917    static final int FINISH_BOOTING_MSG = 45;
1918    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1919    static final int DISMISS_DIALOG_UI_MSG = 48;
1920    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1921    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1922    static final int DELETE_DUMPHEAP_MSG = 51;
1923    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1924    static final int REPORT_TIME_TRACKER_MSG = 54;
1925    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1926    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1927    static final int IDLE_UIDS_MSG = 58;
1928    static final int LOG_STACK_STATE = 60;
1929    static final int VR_MODE_CHANGE_MSG = 61;
1930    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1931    static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
1932    static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
1933    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1934    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1935    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1936    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1937    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1938
1939    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1940    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1941    static final int FIRST_COMPAT_MODE_MSG = 300;
1942    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1943
1944    static final String SERVICE_RECORD_KEY = "servicerecord";
1945
1946    static ServiceThread sKillThread = null;
1947    static KillHandler sKillHandler = null;
1948
1949    CompatModeDialog mCompatModeDialog;
1950    long mLastMemUsageReportTime = 0;
1951
1952    /**
1953     * Flag whether the current user is a "monkey", i.e. whether
1954     * the UI is driven by a UI automation tool.
1955     */
1956    private boolean mUserIsMonkey;
1957
1958    /** The dimensions of the thumbnails in the Recents UI. */
1959    int mThumbnailWidth;
1960    int mThumbnailHeight;
1961    float mFullscreenThumbnailScale;
1962
1963    final ServiceThread mHandlerThread;
1964    final MainHandler mHandler;
1965    final Handler mUiHandler;
1966    final ServiceThread mProcStartHandlerThread;
1967    final Handler mProcStartHandler;
1968
1969    final ActivityManagerConstants mConstants;
1970
1971    // Encapsulates the global setting "hidden_api_blacklist_exemptions"
1972    final HiddenApiSettings mHiddenApiBlacklist;
1973
1974    PackageManagerInternal mPackageManagerInt;
1975
1976    // VoiceInteraction session ID that changes for each new request except when
1977    // being called for multiwindow assist in a single session.
1978    private int mViSessionId = 1000;
1979
1980    final boolean mPermissionReviewRequired;
1981
1982    boolean mHasHeavyWeightFeature;
1983
1984    /**
1985     * Whether to force background check on all apps (for battery saver) or not.
1986     */
1987    boolean mForceBackgroundCheck;
1988
1989    private static String sTheRealBuildSerial = Build.UNKNOWN;
1990
1991    /**
1992     * Current global configuration information. Contains general settings for the entire system,
1993     * also corresponds to the merged configuration of the default display.
1994     */
1995    Configuration getGlobalConfiguration() {
1996        return mStackSupervisor.getConfiguration();
1997    }
1998
1999    final class KillHandler extends Handler {
2000        static final int KILL_PROCESS_GROUP_MSG = 4000;
2001
2002        public KillHandler(Looper looper) {
2003            super(looper, null, true);
2004        }
2005
2006        @Override
2007        public void handleMessage(Message msg) {
2008            switch (msg.what) {
2009                case KILL_PROCESS_GROUP_MSG:
2010                {
2011                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2012                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
2013                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2014                }
2015                break;
2016
2017                default:
2018                    super.handleMessage(msg);
2019            }
2020        }
2021    }
2022
2023    final class UiHandler extends Handler {
2024        public UiHandler() {
2025            super(com.android.server.UiThread.get().getLooper(), null, true);
2026        }
2027
2028        @Override
2029        public void handleMessage(Message msg) {
2030            switch (msg.what) {
2031            case SHOW_ERROR_UI_MSG: {
2032                mAppErrors.handleShowAppErrorUi(msg);
2033                ensureBootCompleted();
2034            } break;
2035            case SHOW_NOT_RESPONDING_UI_MSG: {
2036                mAppErrors.handleShowAnrUi(msg);
2037                ensureBootCompleted();
2038            } break;
2039            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
2040                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
2041                synchronized (ActivityManagerService.this) {
2042                    ProcessRecord proc = (ProcessRecord) data.get("app");
2043                    if (proc == null) {
2044                        Slog.e(TAG, "App not found when showing strict mode dialog.");
2045                        break;
2046                    }
2047                    if (proc.crashDialog != null) {
2048                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
2049                        return;
2050                    }
2051                    AppErrorResult res = (AppErrorResult) data.get("result");
2052                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
2053                        Dialog d = new StrictModeViolationDialog(mUiContext,
2054                                ActivityManagerService.this, res, proc);
2055                        d.show();
2056                        proc.crashDialog = d;
2057                    } else {
2058                        // The device is asleep, so just pretend that the user
2059                        // saw a crash dialog and hit "force quit".
2060                        res.set(0);
2061                    }
2062                }
2063                ensureBootCompleted();
2064            } break;
2065            case SHOW_FACTORY_ERROR_UI_MSG: {
2066                Dialog d = new FactoryErrorDialog(
2067                        mUiContext, msg.getData().getCharSequence("msg"));
2068                d.show();
2069                ensureBootCompleted();
2070            } break;
2071            case WAIT_FOR_DEBUGGER_UI_MSG: {
2072                synchronized (ActivityManagerService.this) {
2073                    ProcessRecord app = (ProcessRecord)msg.obj;
2074                    if (msg.arg1 != 0) {
2075                        if (!app.waitedForDebugger) {
2076                            Dialog d = new AppWaitingForDebuggerDialog(
2077                                    ActivityManagerService.this,
2078                                    mUiContext, app);
2079                            app.waitDialog = d;
2080                            app.waitedForDebugger = true;
2081                            d.show();
2082                        }
2083                    } else {
2084                        if (app.waitDialog != null) {
2085                            app.waitDialog.dismiss();
2086                            app.waitDialog = null;
2087                        }
2088                    }
2089                }
2090            } break;
2091            case SHOW_UID_ERROR_UI_MSG: {
2092                if (mShowDialogs) {
2093                    AlertDialog d = new BaseErrorDialog(mUiContext);
2094                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2095                    d.setCancelable(false);
2096                    d.setTitle(mUiContext.getText(R.string.android_system_label));
2097                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
2098                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2099                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2100                    d.show();
2101                }
2102            } break;
2103            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
2104                if (mShowDialogs) {
2105                    AlertDialog d = new BaseErrorDialog(mUiContext);
2106                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2107                    d.setCancelable(false);
2108                    d.setTitle(mUiContext.getText(R.string.android_system_label));
2109                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
2110                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2111                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2112                    d.show();
2113                }
2114            } break;
2115            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
2116                synchronized (ActivityManagerService.this) {
2117                    ActivityRecord ar = (ActivityRecord) msg.obj;
2118                    if (mCompatModeDialog != null) {
2119                        if (mCompatModeDialog.mAppInfo.packageName.equals(
2120                                ar.info.applicationInfo.packageName)) {
2121                            return;
2122                        }
2123                        mCompatModeDialog.dismiss();
2124                        mCompatModeDialog = null;
2125                    }
2126                    if (ar != null && false) {
2127                        if (mCompatModePackages.getPackageAskCompatModeLocked(
2128                                ar.packageName)) {
2129                            int mode = mCompatModePackages.computeCompatModeLocked(
2130                                    ar.info.applicationInfo);
2131                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
2132                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
2133                                mCompatModeDialog = new CompatModeDialog(
2134                                        ActivityManagerService.this, mUiContext,
2135                                        ar.info.applicationInfo);
2136                                mCompatModeDialog.show();
2137                            }
2138                        }
2139                    }
2140                }
2141                break;
2142            }
2143            case DISMISS_DIALOG_UI_MSG: {
2144                final Dialog d = (Dialog) msg.obj;
2145                d.dismiss();
2146                break;
2147            }
2148            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
2149                dispatchProcessesChanged();
2150                break;
2151            }
2152            case DISPATCH_PROCESS_DIED_UI_MSG: {
2153                final int pid = msg.arg1;
2154                final int uid = msg.arg2;
2155                dispatchProcessDied(pid, uid);
2156                break;
2157            }
2158            case DISPATCH_UIDS_CHANGED_UI_MSG: {
2159                dispatchUidsChanged();
2160            } break;
2161            case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
2162                dispatchOomAdjObserver((String)msg.obj);
2163            } break;
2164            case PUSH_TEMP_WHITELIST_UI_MSG: {
2165                pushTempWhitelist();
2166            } break;
2167            }
2168        }
2169    }
2170
2171    final class MainHandler extends Handler {
2172        public MainHandler(Looper looper) {
2173            super(looper, null, true);
2174        }
2175
2176        @Override
2177        public void handleMessage(Message msg) {
2178            switch (msg.what) {
2179            case UPDATE_CONFIGURATION_MSG: {
2180                final ContentResolver resolver = mContext.getContentResolver();
2181                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
2182                        msg.arg1);
2183            } break;
2184            case GC_BACKGROUND_PROCESSES_MSG: {
2185                synchronized (ActivityManagerService.this) {
2186                    performAppGcsIfAppropriateLocked();
2187                }
2188            } break;
2189            case SERVICE_TIMEOUT_MSG: {
2190                mServices.serviceTimeout((ProcessRecord)msg.obj);
2191            } break;
2192            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
2193                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
2194            } break;
2195            case SERVICE_FOREGROUND_CRASH_MSG: {
2196                mServices.serviceForegroundCrash(
2197                    (ProcessRecord) msg.obj, msg.getData().getCharSequence(SERVICE_RECORD_KEY));
2198            } break;
2199            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
2200                RemoteCallbackList<IResultReceiver> callbacks
2201                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
2202                int N = callbacks.beginBroadcast();
2203                for (int i = 0; i < N; i++) {
2204                    try {
2205                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
2206                    } catch (RemoteException e) {
2207                    }
2208                }
2209                callbacks.finishBroadcast();
2210            } break;
2211            case UPDATE_TIME_ZONE: {
2212                synchronized (ActivityManagerService.this) {
2213                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2214                        ProcessRecord r = mLruProcesses.get(i);
2215                        if (r.thread != null) {
2216                            try {
2217                                r.thread.updateTimeZone();
2218                            } catch (RemoteException ex) {
2219                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2220                            }
2221                        }
2222                    }
2223                }
2224            } break;
2225            case CLEAR_DNS_CACHE_MSG: {
2226                synchronized (ActivityManagerService.this) {
2227                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2228                        ProcessRecord r = mLruProcesses.get(i);
2229                        if (r.thread != null) {
2230                            try {
2231                                r.thread.clearDnsCache();
2232                            } catch (RemoteException ex) {
2233                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2234                            }
2235                        }
2236                    }
2237                }
2238            } break;
2239            case UPDATE_HTTP_PROXY_MSG: {
2240                ProxyInfo proxy = (ProxyInfo)msg.obj;
2241                String host = "";
2242                String port = "";
2243                String exclList = "";
2244                Uri pacFileUrl = Uri.EMPTY;
2245                if (proxy != null) {
2246                    host = proxy.getHost();
2247                    port = Integer.toString(proxy.getPort());
2248                    exclList = proxy.getExclusionListAsString();
2249                    pacFileUrl = proxy.getPacFileUrl();
2250                }
2251                synchronized (ActivityManagerService.this) {
2252                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2253                        ProcessRecord r = mLruProcesses.get(i);
2254                        // Don't dispatch to isolated processes as they can't access
2255                        // ConnectivityManager and don't have network privileges anyway.
2256                        if (r.thread != null && !r.isolated) {
2257                            try {
2258                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2259                            } catch (RemoteException ex) {
2260                                Slog.w(TAG, "Failed to update http proxy for: " +
2261                                        r.info.processName);
2262                            }
2263                        }
2264                    }
2265                }
2266            } break;
2267            case PROC_START_TIMEOUT_MSG: {
2268                ProcessRecord app = (ProcessRecord)msg.obj;
2269                synchronized (ActivityManagerService.this) {
2270                    processStartTimedOutLocked(app);
2271                }
2272            } break;
2273            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2274                ProcessRecord app = (ProcessRecord)msg.obj;
2275                synchronized (ActivityManagerService.this) {
2276                    processContentProviderPublishTimedOutLocked(app);
2277                }
2278            } break;
2279            case KILL_APPLICATION_MSG: {
2280                synchronized (ActivityManagerService.this) {
2281                    final int appId = msg.arg1;
2282                    final int userId = msg.arg2;
2283                    Bundle bundle = (Bundle)msg.obj;
2284                    String pkg = bundle.getString("pkg");
2285                    String reason = bundle.getString("reason");
2286                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2287                            false, userId, reason);
2288                }
2289            } break;
2290            case FINALIZE_PENDING_INTENT_MSG: {
2291                ((PendingIntentRecord)msg.obj).completeFinalize();
2292            } break;
2293            case POST_HEAVY_NOTIFICATION_MSG: {
2294                INotificationManager inm = NotificationManager.getService();
2295                if (inm == null) {
2296                    return;
2297                }
2298
2299                ActivityRecord root = (ActivityRecord)msg.obj;
2300                ProcessRecord process = root.app;
2301                if (process == null) {
2302                    return;
2303                }
2304
2305                try {
2306                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2307                    String text = mContext.getString(R.string.heavy_weight_notification,
2308                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2309                    Notification notification =
2310                            new Notification.Builder(context,
2311                                    SystemNotificationChannels.HEAVY_WEIGHT_APP)
2312                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2313                            .setWhen(0)
2314                            .setOngoing(true)
2315                            .setTicker(text)
2316                            .setColor(mContext.getColor(
2317                                    com.android.internal.R.color.system_notification_accent_color))
2318                            .setContentTitle(text)
2319                            .setContentText(
2320                                    mContext.getText(R.string.heavy_weight_notification_detail))
2321                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2322                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2323                                    new UserHandle(root.userId)))
2324                            .build();
2325                    try {
2326                        inm.enqueueNotificationWithTag("android", "android", null,
2327                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2328                                notification, root.userId);
2329                    } catch (RuntimeException e) {
2330                        Slog.w(ActivityManagerService.TAG,
2331                                "Error showing notification for heavy-weight app", e);
2332                    } catch (RemoteException e) {
2333                    }
2334                } catch (NameNotFoundException e) {
2335                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2336                }
2337            } break;
2338            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2339                INotificationManager inm = NotificationManager.getService();
2340                if (inm == null) {
2341                    return;
2342                }
2343                try {
2344                    inm.cancelNotificationWithTag("android", null,
2345                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2346                } catch (RuntimeException e) {
2347                    Slog.w(ActivityManagerService.TAG,
2348                            "Error canceling notification for service", e);
2349                } catch (RemoteException e) {
2350                }
2351            } break;
2352            case CHECK_EXCESSIVE_POWER_USE_MSG: {
2353                synchronized (ActivityManagerService.this) {
2354                    checkExcessivePowerUsageLocked();
2355                    removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2356                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2357                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2358                }
2359            } break;
2360            case REPORT_MEM_USAGE_MSG: {
2361                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2362                Thread thread = new Thread() {
2363                    @Override public void run() {
2364                        reportMemUsage(memInfos);
2365                    }
2366                };
2367                thread.start();
2368                break;
2369            }
2370            case IMMERSIVE_MODE_LOCK_MSG: {
2371                final boolean nextState = (msg.arg1 != 0);
2372                if (mUpdateLock.isHeld() != nextState) {
2373                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2374                            "Applying new update lock state '" + nextState
2375                            + "' for " + (ActivityRecord)msg.obj);
2376                    if (nextState) {
2377                        mUpdateLock.acquire();
2378                    } else {
2379                        mUpdateLock.release();
2380                    }
2381                }
2382                break;
2383            }
2384            case PERSIST_URI_GRANTS_MSG: {
2385                writeGrantedUriPermissions();
2386                break;
2387            }
2388            case UPDATE_TIME_PREFERENCE_MSG: {
2389                // The user's time format preference might have changed.
2390                // For convenience we re-use the Intent extra values.
2391                synchronized (ActivityManagerService.this) {
2392                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2393                        ProcessRecord r = mLruProcesses.get(i);
2394                        if (r.thread != null) {
2395                            try {
2396                                r.thread.updateTimePrefs(msg.arg1);
2397                            } catch (RemoteException ex) {
2398                                Slog.w(TAG, "Failed to update preferences for: "
2399                                        + r.info.processName);
2400                            }
2401                        }
2402                    }
2403                }
2404                break;
2405            }
2406            case ENTER_ANIMATION_COMPLETE_MSG: {
2407                synchronized (ActivityManagerService.this) {
2408                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2409                    if (r != null && r.app != null && r.app.thread != null) {
2410                        try {
2411                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2412                        } catch (RemoteException e) {
2413                        }
2414                    }
2415                }
2416                break;
2417            }
2418            case FINISH_BOOTING_MSG: {
2419                if (msg.arg1 != 0) {
2420                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2421                    finishBooting();
2422                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2423                }
2424                if (msg.arg2 != 0) {
2425                    enableScreenAfterBoot();
2426                }
2427                break;
2428            }
2429            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2430                try {
2431                    Locale l = (Locale) msg.obj;
2432                    IBinder service = ServiceManager.getService("mount");
2433                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2434                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2435                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2436                } catch (RemoteException e) {
2437                    Log.e(TAG, "Error storing locale for decryption UI", e);
2438                }
2439                break;
2440            }
2441            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2442                final int uid = msg.arg1;
2443                final byte[] firstPacket = (byte[]) msg.obj;
2444
2445                synchronized (mPidsSelfLocked) {
2446                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2447                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2448                        if (p.uid == uid) {
2449                            try {
2450                                p.thread.notifyCleartextNetwork(firstPacket);
2451                            } catch (RemoteException ignored) {
2452                            }
2453                        }
2454                    }
2455                }
2456                break;
2457            }
2458            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2459                final String procName;
2460                final int uid;
2461                final long memLimit;
2462                final String reportPackage;
2463                synchronized (ActivityManagerService.this) {
2464                    procName = mMemWatchDumpProcName;
2465                    uid = mMemWatchDumpUid;
2466                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2467                    if (val == null) {
2468                        val = mMemWatchProcesses.get(procName, 0);
2469                    }
2470                    if (val != null) {
2471                        memLimit = val.first;
2472                        reportPackage = val.second;
2473                    } else {
2474                        memLimit = 0;
2475                        reportPackage = null;
2476                    }
2477                }
2478                if (procName == null) {
2479                    return;
2480                }
2481
2482                if (DEBUG_PSS) Slog.d(TAG_PSS,
2483                        "Showing dump heap notification from " + procName + "/" + uid);
2484
2485                INotificationManager inm = NotificationManager.getService();
2486                if (inm == null) {
2487                    return;
2488                }
2489
2490                String text = mContext.getString(R.string.dump_heap_notification, procName);
2491
2492
2493                Intent deleteIntent = new Intent();
2494                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2495                Intent intent = new Intent();
2496                intent.setClassName("android", DumpHeapActivity.class.getName());
2497                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2498                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2499                if (reportPackage != null) {
2500                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2501                }
2502                int userId = UserHandle.getUserId(uid);
2503                Notification notification =
2504                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2505                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2506                        .setWhen(0)
2507                        .setOngoing(true)
2508                        .setAutoCancel(true)
2509                        .setTicker(text)
2510                        .setColor(mContext.getColor(
2511                                com.android.internal.R.color.system_notification_accent_color))
2512                        .setContentTitle(text)
2513                        .setContentText(
2514                                mContext.getText(R.string.dump_heap_notification_detail))
2515                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2516                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2517                                new UserHandle(userId)))
2518                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2519                                deleteIntent, 0, UserHandle.SYSTEM))
2520                        .build();
2521
2522                try {
2523                    inm.enqueueNotificationWithTag("android", "android", null,
2524                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2525                            notification, userId);
2526                } catch (RuntimeException e) {
2527                    Slog.w(ActivityManagerService.TAG,
2528                            "Error showing notification for dump heap", e);
2529                } catch (RemoteException e) {
2530                }
2531            } break;
2532            case DELETE_DUMPHEAP_MSG: {
2533                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2534                        null, DumpHeapActivity.JAVA_URI,
2535                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2536                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2537                        UserHandle.myUserId());
2538                synchronized (ActivityManagerService.this) {
2539                    mMemWatchDumpFile = null;
2540                    mMemWatchDumpProcName = null;
2541                    mMemWatchDumpPid = -1;
2542                    mMemWatchDumpUid = -1;
2543                }
2544            } break;
2545            case REPORT_TIME_TRACKER_MSG: {
2546                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2547                tracker.deliverResult(mContext);
2548            } break;
2549            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2550                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2551                try {
2552                    connection.shutdown();
2553                } catch (RemoteException e) {
2554                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2555                }
2556                // Only a UiAutomation can set this flag and now that
2557                // it is finished we make sure it is reset to its default.
2558                mUserIsMonkey = false;
2559            } break;
2560            case IDLE_UIDS_MSG: {
2561                idleUids();
2562            } break;
2563            case VR_MODE_CHANGE_MSG: {
2564                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2565                    return;
2566                }
2567                synchronized (ActivityManagerService.this) {
2568                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2569                    mWindowManager.disableNonVrUi(disableNonVrUi);
2570                    if (disableNonVrUi) {
2571                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2572                        // then remove the pinned stack.
2573                        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2574                    }
2575                }
2576            } break;
2577            case DISPATCH_SCREEN_AWAKE_MSG: {
2578                final boolean isAwake = msg.arg1 != 0;
2579                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2580                    mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2581                }
2582            } break;
2583            case DISPATCH_SCREEN_KEYGUARD_MSG: {
2584                final boolean isShowing = msg.arg1 != 0;
2585                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2586                    mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2587                }
2588            } break;
2589            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2590                synchronized (ActivityManagerService.this) {
2591                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2592                        ProcessRecord r = mLruProcesses.get(i);
2593                        if (r.thread != null) {
2594                            try {
2595                                r.thread.handleTrustStorageUpdate();
2596                            } catch (RemoteException ex) {
2597                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2598                                        r.info.processName);
2599                            }
2600                        }
2601                    }
2602                }
2603            } break;
2604            }
2605        }
2606    };
2607
2608    static final int COLLECT_PSS_BG_MSG = 1;
2609
2610    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2611        @Override
2612        public void handleMessage(Message msg) {
2613            switch (msg.what) {
2614            case COLLECT_PSS_BG_MSG: {
2615                long start = SystemClock.uptimeMillis();
2616                MemInfoReader memInfo = null;
2617                synchronized (ActivityManagerService.this) {
2618                    if (mFullPssPending) {
2619                        mFullPssPending = false;
2620                        memInfo = new MemInfoReader();
2621                    }
2622                }
2623                if (memInfo != null) {
2624                    updateCpuStatsNow();
2625                    long nativeTotalPss = 0;
2626                    final List<ProcessCpuTracker.Stats> stats;
2627                    synchronized (mProcessCpuTracker) {
2628                        stats = mProcessCpuTracker.getStats( (st)-> {
2629                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2630                        });
2631                    }
2632                    final int N = stats.size();
2633                    for (int j = 0; j < N; j++) {
2634                        synchronized (mPidsSelfLocked) {
2635                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2636                                // This is one of our own processes; skip it.
2637                                continue;
2638                            }
2639                        }
2640                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2641                    }
2642                    memInfo.readMemInfo();
2643                    synchronized (ActivityManagerService.this) {
2644                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2645                                + (SystemClock.uptimeMillis()-start) + "ms");
2646                        final long cachedKb = memInfo.getCachedSizeKb();
2647                        final long freeKb = memInfo.getFreeSizeKb();
2648                        final long zramKb = memInfo.getZramTotalSizeKb();
2649                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2650                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2651                                kernelKb*1024, nativeTotalPss*1024);
2652                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2653                                nativeTotalPss);
2654                    }
2655                }
2656
2657                int num = 0;
2658                long[] tmp = new long[3];
2659                do {
2660                    ProcessRecord proc;
2661                    int procState;
2662                    int statType;
2663                    int pid;
2664                    long lastPssTime;
2665                    synchronized (ActivityManagerService.this) {
2666                        if (mPendingPssProcesses.size() <= 0) {
2667                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2668                                    "Collected pss of " + num + " processes in "
2669                                    + (SystemClock.uptimeMillis() - start) + "ms");
2670                            mPendingPssProcesses.clear();
2671                            return;
2672                        }
2673                        proc = mPendingPssProcesses.remove(0);
2674                        procState = proc.pssProcState;
2675                        statType = proc.pssStatType;
2676                        lastPssTime = proc.lastPssTime;
2677                        long now = SystemClock.uptimeMillis();
2678                        if (proc.thread != null && procState == proc.setProcState
2679                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2680                                        < now) {
2681                            pid = proc.pid;
2682                        } else {
2683                            ProcessList.abortNextPssTime(proc.procStateMemTracker);
2684                            if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2685                                    ": still need " +
2686                                    (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE-now) +
2687                                    "ms until safe");
2688                            proc = null;
2689                            pid = 0;
2690                        }
2691                    }
2692                    if (proc != null) {
2693                        long startTime = SystemClock.currentThreadTimeMillis();
2694                        long pss = Debug.getPss(pid, tmp, null);
2695                        long endTime = SystemClock.currentThreadTimeMillis();
2696                        synchronized (ActivityManagerService.this) {
2697                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2698                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2699                                num++;
2700                                ProcessList.commitNextPssTime(proc.procStateMemTracker);
2701                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], tmp[2],
2702                                        statType, endTime-startTime, SystemClock.uptimeMillis());
2703                            } else {
2704                                ProcessList.abortNextPssTime(proc.procStateMemTracker);
2705                                if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2706                                        ": " + (proc.thread == null ? "NO_THREAD " : "") +
2707                                        (proc.pid != pid ? "PID_CHANGED " : "") +
2708                                        " initState=" + procState + " curState=" +
2709                                        proc.setProcState + " " +
2710                                        (proc.lastPssTime != lastPssTime ? "TIME_CHANGED" : ""));
2711                            }
2712                        }
2713                    }
2714                } while (true);
2715            }
2716            }
2717        }
2718    };
2719
2720    public void setSystemProcess() {
2721        try {
2722            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
2723                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
2724            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2725            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
2726                    DUMP_FLAG_PRIORITY_HIGH);
2727            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2728            ServiceManager.addService("dbinfo", new DbBinder(this));
2729            if (MONITOR_CPU_USAGE) {
2730                ServiceManager.addService("cpuinfo", new CpuBinder(this),
2731                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
2732            }
2733            ServiceManager.addService("permission", new PermissionController(this));
2734            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2735
2736            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2737                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2738            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2739
2740            synchronized (this) {
2741                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2742                app.persistent = true;
2743                app.pid = MY_PID;
2744                app.maxAdj = ProcessList.SYSTEM_ADJ;
2745                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2746                synchronized (mPidsSelfLocked) {
2747                    mPidsSelfLocked.put(app.pid, app);
2748                }
2749                updateLruProcessLocked(app, false, null);
2750                updateOomAdjLocked();
2751            }
2752        } catch (PackageManager.NameNotFoundException e) {
2753            throw new RuntimeException(
2754                    "Unable to find android system package", e);
2755        }
2756
2757        // Start watching app ops after we and the package manager are up and running.
2758        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2759                new IAppOpsCallback.Stub() {
2760                    @Override public void opChanged(int op, int uid, String packageName) {
2761                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2762                            if (mAppOpsService.checkOperation(op, uid, packageName)
2763                                    != AppOpsManager.MODE_ALLOWED) {
2764                                runInBackgroundDisabled(uid);
2765                            }
2766                        }
2767                    }
2768                });
2769    }
2770
2771    public void setWindowManager(WindowManagerService wm) {
2772        synchronized (this) {
2773            mWindowManager = wm;
2774            mStackSupervisor.setWindowManager(wm);
2775            mLockTaskController.setWindowManager(wm);
2776        }
2777    }
2778
2779    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2780        mUsageStatsService = usageStatsManager;
2781    }
2782
2783    public void startObservingNativeCrashes() {
2784        final NativeCrashListener ncl = new NativeCrashListener(this);
2785        ncl.start();
2786    }
2787
2788    public IAppOpsService getAppOpsService() {
2789        return mAppOpsService;
2790    }
2791
2792    static class MemBinder extends Binder {
2793        ActivityManagerService mActivityManagerService;
2794        private final PriorityDump.PriorityDumper mPriorityDumper =
2795                new PriorityDump.PriorityDumper() {
2796            @Override
2797            public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args,
2798                    boolean asProto) {
2799                dump(fd, pw, new String[] {"-a"}, asProto);
2800            }
2801
2802            @Override
2803            public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
2804                mActivityManagerService.dumpApplicationMemoryUsage(
2805                        fd, pw, "  ", args, false, null, asProto);
2806            }
2807        };
2808
2809        MemBinder(ActivityManagerService activityManagerService) {
2810            mActivityManagerService = activityManagerService;
2811        }
2812
2813        @Override
2814        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2815            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2816                    "meminfo", pw)) return;
2817            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2818        }
2819    }
2820
2821    static class GraphicsBinder extends Binder {
2822        ActivityManagerService mActivityManagerService;
2823        GraphicsBinder(ActivityManagerService activityManagerService) {
2824            mActivityManagerService = activityManagerService;
2825        }
2826
2827        @Override
2828        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2829            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2830                    "gfxinfo", pw)) return;
2831            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2832        }
2833    }
2834
2835    static class DbBinder extends Binder {
2836        ActivityManagerService mActivityManagerService;
2837        DbBinder(ActivityManagerService activityManagerService) {
2838            mActivityManagerService = activityManagerService;
2839        }
2840
2841        @Override
2842        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2843            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2844                    "dbinfo", pw)) return;
2845            mActivityManagerService.dumpDbInfo(fd, pw, args);
2846        }
2847    }
2848
2849    static class CpuBinder extends Binder {
2850        ActivityManagerService mActivityManagerService;
2851        private final PriorityDump.PriorityDumper mPriorityDumper =
2852                new PriorityDump.PriorityDumper() {
2853            @Override
2854            public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
2855                    boolean asProto) {
2856                if (asProto) return;
2857                if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2858                        "cpuinfo", pw)) return;
2859                synchronized (mActivityManagerService.mProcessCpuTracker) {
2860                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2861                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2862                            SystemClock.uptimeMillis()));
2863                }
2864            }
2865        };
2866
2867        CpuBinder(ActivityManagerService activityManagerService) {
2868            mActivityManagerService = activityManagerService;
2869        }
2870
2871        @Override
2872        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2873            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2874        }
2875    }
2876
2877    public static final class Lifecycle extends SystemService {
2878        private final ActivityManagerService mService;
2879
2880        public Lifecycle(Context context) {
2881            super(context);
2882            mService = new ActivityManagerService(context);
2883        }
2884
2885        @Override
2886        public void onStart() {
2887            mService.start();
2888        }
2889
2890        @Override
2891        public void onBootPhase(int phase) {
2892            mService.mBootPhase = phase;
2893            if (phase == PHASE_SYSTEM_SERVICES_READY) {
2894                mService.mBatteryStatsService.systemServicesReady();
2895                mService.mServices.systemServicesReady();
2896            }
2897        }
2898
2899        @Override
2900        public void onCleanupUser(int userId) {
2901            mService.mBatteryStatsService.onCleanupUser(userId);
2902        }
2903
2904        public ActivityManagerService getService() {
2905            return mService;
2906        }
2907    }
2908
2909    /**
2910     * Encapsulates global settings related to hidden API enforcement behaviour, including tracking
2911     * the latest value via a content observer.
2912     */
2913    static class HiddenApiSettings extends ContentObserver {
2914
2915        private final Context mContext;
2916        private boolean mBlacklistDisabled;
2917        private String mExemptionsStr;
2918        private List<String> mExemptions = Collections.emptyList();
2919        private int mLogSampleRate = -1;
2920        @HiddenApiEnforcementPolicy private int mPolicyPreP = HIDDEN_API_ENFORCEMENT_DEFAULT;
2921        @HiddenApiEnforcementPolicy private int mPolicyP = HIDDEN_API_ENFORCEMENT_DEFAULT;
2922
2923        public HiddenApiSettings(Handler handler, Context context) {
2924            super(handler);
2925            mContext = context;
2926        }
2927
2928        public void registerObserver() {
2929            mContext.getContentResolver().registerContentObserver(
2930                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS),
2931                    false,
2932                    this);
2933            mContext.getContentResolver().registerContentObserver(
2934                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE),
2935                    false,
2936                    this);
2937            mContext.getContentResolver().registerContentObserver(
2938                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS),
2939                    false,
2940                    this);
2941            mContext.getContentResolver().registerContentObserver(
2942                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_P_APPS),
2943                    false,
2944                    this);
2945            update();
2946        }
2947
2948        private void update() {
2949            String exemptions = Settings.Global.getString(mContext.getContentResolver(),
2950                    Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS);
2951            if (!TextUtils.equals(exemptions, mExemptionsStr)) {
2952                mExemptionsStr = exemptions;
2953                if ("*".equals(exemptions)) {
2954                    mBlacklistDisabled = true;
2955                    mExemptions = Collections.emptyList();
2956                } else {
2957                    mBlacklistDisabled = false;
2958                    mExemptions = TextUtils.isEmpty(exemptions)
2959                            ? Collections.emptyList()
2960                            : Arrays.asList(exemptions.split(","));
2961                }
2962                if (!zygoteProcess.setApiBlacklistExemptions(mExemptions)) {
2963                  Slog.e(TAG, "Failed to set API blacklist exemptions!");
2964                  // leave mExemptionsStr as is, so we don't try to send the same list again.
2965                  mExemptions = Collections.emptyList();
2966                }
2967            }
2968            int logSampleRate = Settings.Global.getInt(mContext.getContentResolver(),
2969                    Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, -1);
2970            if (logSampleRate < 0 || logSampleRate > 0x10000) {
2971                logSampleRate = -1;
2972            }
2973            if (logSampleRate != -1 && logSampleRate != mLogSampleRate) {
2974                mLogSampleRate = logSampleRate;
2975                zygoteProcess.setHiddenApiAccessLogSampleRate(mLogSampleRate);
2976            }
2977            mPolicyPreP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS);
2978            mPolicyP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_P_APPS);
2979        }
2980
2981        private @HiddenApiEnforcementPolicy int getValidEnforcementPolicy(String settingsKey) {
2982            int policy = Settings.Global.getInt(mContext.getContentResolver(), settingsKey,
2983                    ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT);
2984            if (ApplicationInfo.isValidHiddenApiEnforcementPolicy(policy)) {
2985                return policy;
2986            } else {
2987                return ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
2988            }
2989        }
2990
2991        boolean isDisabled() {
2992            return mBlacklistDisabled;
2993        }
2994
2995        @HiddenApiEnforcementPolicy int getPolicyForPrePApps() {
2996            return mPolicyPreP;
2997        }
2998
2999        @HiddenApiEnforcementPolicy int getPolicyForPApps() {
3000            return mPolicyP;
3001        }
3002
3003        public void onChange(boolean selfChange) {
3004            update();
3005        }
3006    }
3007
3008    @VisibleForTesting
3009    public ActivityManagerService(Injector injector) {
3010        mInjector = injector;
3011        mContext = mInjector.getContext();
3012        mUiContext = null;
3013        GL_ES_VERSION = 0;
3014        mActivityStartController = null;
3015        mAppErrors = null;
3016        mAppWarnings = null;
3017        mAppOpsService = mInjector.getAppOpsService(null, null);
3018        mBatteryStatsService = null;
3019        mCompatModePackages = null;
3020        mConstants = null;
3021        mGrantFile = null;
3022        mHandler = null;
3023        mHandlerThread = null;
3024        mIntentFirewall = null;
3025        mKeyguardController = null;
3026        mPermissionReviewRequired = false;
3027        mProcessCpuThread = null;
3028        mProcessStats = null;
3029        mProviderMap = null;
3030        mRecentTasks = null;
3031        mServices = null;
3032        mStackSupervisor = null;
3033        mSystemThread = null;
3034        mTaskChangeNotificationController = null;
3035        mUiHandler = injector.getUiHandler(null);
3036        mUserController = null;
3037        mVrController = null;
3038        mLockTaskController = null;
3039        mLifecycleManager = null;
3040        mProcStartHandlerThread = null;
3041        mProcStartHandler = null;
3042        mHiddenApiBlacklist = null;
3043    }
3044
3045    // Note: This method is invoked on the main thread but may need to attach various
3046    // handlers to other threads.  So take care to be explicit about the looper.
3047    public ActivityManagerService(Context systemContext) {
3048        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
3049        mInjector = new Injector();
3050        mContext = systemContext;
3051
3052        mFactoryTest = FactoryTest.getMode();
3053        mSystemThread = ActivityThread.currentActivityThread();
3054        mUiContext = mSystemThread.getSystemUiContext();
3055
3056        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
3057
3058        mPermissionReviewRequired = mContext.getResources().getBoolean(
3059                com.android.internal.R.bool.config_permissionReviewRequired);
3060
3061        mHandlerThread = new ServiceThread(TAG,
3062                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
3063        mHandlerThread.start();
3064        mHandler = new MainHandler(mHandlerThread.getLooper());
3065        mUiHandler = mInjector.getUiHandler(this);
3066
3067        mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
3068                THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
3069        mProcStartHandlerThread.start();
3070        mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
3071
3072        mConstants = new ActivityManagerConstants(this, mHandler);
3073
3074        /* static; one-time init here */
3075        if (sKillHandler == null) {
3076            sKillThread = new ServiceThread(TAG + ":kill",
3077                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
3078            sKillThread.start();
3079            sKillHandler = new KillHandler(sKillThread.getLooper());
3080        }
3081
3082        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
3083                "foreground", BROADCAST_FG_TIMEOUT, false);
3084        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
3085                "background", BROADCAST_BG_TIMEOUT, true);
3086        mBroadcastQueues[0] = mFgBroadcastQueue;
3087        mBroadcastQueues[1] = mBgBroadcastQueue;
3088
3089        mServices = new ActiveServices(this);
3090        mProviderMap = new ProviderMap(this);
3091        mAppErrors = new AppErrors(mUiContext, this);
3092
3093        File dataDir = Environment.getDataDirectory();
3094        File systemDir = new File(dataDir, "system");
3095        systemDir.mkdirs();
3096
3097        mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
3098
3099        // TODO: Move creation of battery stats service outside of activity manager service.
3100        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
3101        mBatteryStatsService.getActiveStatistics().readLocked();
3102        mBatteryStatsService.scheduleWriteToDisk();
3103        mOnBattery = DEBUG_POWER ? true
3104                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
3105        mBatteryStatsService.getActiveStatistics().setCallback(this);
3106
3107        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
3108
3109        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
3110
3111        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
3112
3113        mUserController = new UserController(this);
3114
3115        mVrController = new VrController(this);
3116
3117        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
3118            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
3119
3120        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
3121            mUseFifoUiScheduling = true;
3122        }
3123
3124        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
3125        mTempConfig.setToDefaults();
3126        mTempConfig.setLocales(LocaleList.getDefault());
3127        mConfigurationSeq = mTempConfig.seq = 1;
3128        mStackSupervisor = createStackSupervisor();
3129        mStackSupervisor.onConfigurationChanged(mTempConfig);
3130        mKeyguardController = mStackSupervisor.getKeyguardController();
3131        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
3132        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
3133        mTaskChangeNotificationController =
3134                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
3135        mActivityStartController = new ActivityStartController(this);
3136        mRecentTasks = createRecentTasks();
3137        mStackSupervisor.setRecentTasks(mRecentTasks);
3138        mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
3139        mLifecycleManager = new ClientLifecycleManager();
3140
3141        mProcessCpuThread = new Thread("CpuTracker") {
3142            @Override
3143            public void run() {
3144                synchronized (mProcessCpuTracker) {
3145                    mProcessCpuInitLatch.countDown();
3146                    mProcessCpuTracker.init();
3147                }
3148                while (true) {
3149                    try {
3150                        try {
3151                            synchronized(this) {
3152                                final long now = SystemClock.uptimeMillis();
3153                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
3154                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
3155                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
3156                                //        + ", write delay=" + nextWriteDelay);
3157                                if (nextWriteDelay < nextCpuDelay) {
3158                                    nextCpuDelay = nextWriteDelay;
3159                                }
3160                                if (nextCpuDelay > 0) {
3161                                    mProcessCpuMutexFree.set(true);
3162                                    this.wait(nextCpuDelay);
3163                                }
3164                            }
3165                        } catch (InterruptedException e) {
3166                        }
3167                        updateCpuStatsNow();
3168                    } catch (Exception e) {
3169                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
3170                    }
3171                }
3172            }
3173        };
3174
3175        mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext);
3176
3177        Watchdog.getInstance().addMonitor(this);
3178        Watchdog.getInstance().addThread(mHandler);
3179
3180        // bind background thread to little cores
3181        // this is expected to fail inside of framework tests because apps can't touch cpusets directly
3182        // make sure we've already adjusted system_server's internal view of itself first
3183        updateOomAdjLocked();
3184        try {
3185            Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(),
3186                    Process.THREAD_GROUP_BG_NONINTERACTIVE);
3187        } catch (Exception e) {
3188            Slog.w(TAG, "Setting background thread cpuset failed");
3189        }
3190
3191    }
3192
3193    protected ActivityStackSupervisor createStackSupervisor() {
3194        final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
3195        supervisor.initialize();
3196        return supervisor;
3197    }
3198
3199    protected RecentTasks createRecentTasks() {
3200        return new RecentTasks(this, mStackSupervisor);
3201    }
3202
3203    RecentTasks getRecentTasks() {
3204        return mRecentTasks;
3205    }
3206
3207    public void setSystemServiceManager(SystemServiceManager mgr) {
3208        mSystemServiceManager = mgr;
3209    }
3210
3211    public void setInstaller(Installer installer) {
3212        mInstaller = installer;
3213    }
3214
3215    private void start() {
3216        removeAllProcessGroups();
3217        mProcessCpuThread.start();
3218
3219        mBatteryStatsService.publish();
3220        mAppOpsService.publish(mContext);
3221        Slog.d("AppOps", "AppOpsService published");
3222        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
3223        // Wait for the synchronized block started in mProcessCpuThread,
3224        // so that any other acccess to mProcessCpuTracker from main thread
3225        // will be blocked during mProcessCpuTracker initialization.
3226        try {
3227            mProcessCpuInitLatch.await();
3228        } catch (InterruptedException e) {
3229            Slog.wtf(TAG, "Interrupted wait during start", e);
3230            Thread.currentThread().interrupt();
3231            throw new IllegalStateException("Interrupted wait during start");
3232        }
3233    }
3234
3235    void onUserStoppedLocked(int userId) {
3236        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
3237        mAllowAppSwitchUids.remove(userId);
3238    }
3239
3240    public void initPowerManagement() {
3241        mStackSupervisor.initPowerManagement();
3242        mBatteryStatsService.initPowerManagement();
3243        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
3244        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
3245        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
3246        mVoiceWakeLock.setReferenceCounted(false);
3247    }
3248
3249    private ArraySet<String> getBackgroundLaunchBroadcasts() {
3250        if (mBackgroundLaunchBroadcasts == null) {
3251            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
3252        }
3253        return mBackgroundLaunchBroadcasts;
3254    }
3255
3256    @Override
3257    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3258            throws RemoteException {
3259        if (code == SYSPROPS_TRANSACTION) {
3260            // We need to tell all apps about the system property change.
3261            ArrayList<IBinder> procs = new ArrayList<IBinder>();
3262            synchronized(this) {
3263                final int NP = mProcessNames.getMap().size();
3264                for (int ip=0; ip<NP; ip++) {
3265                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
3266                    final int NA = apps.size();
3267                    for (int ia=0; ia<NA; ia++) {
3268                        ProcessRecord app = apps.valueAt(ia);
3269                        if (app.thread != null) {
3270                            procs.add(app.thread.asBinder());
3271                        }
3272                    }
3273                }
3274            }
3275
3276            int N = procs.size();
3277            for (int i=0; i<N; i++) {
3278                Parcel data2 = Parcel.obtain();
3279                try {
3280                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
3281                            Binder.FLAG_ONEWAY);
3282                } catch (RemoteException e) {
3283                }
3284                data2.recycle();
3285            }
3286        }
3287        try {
3288            return super.onTransact(code, data, reply, flags);
3289        } catch (RuntimeException e) {
3290            // The activity manager only throws certain exceptions intentionally, so let's
3291            // log all others.
3292            if (!(e instanceof SecurityException
3293                    || e instanceof IllegalArgumentException
3294                    || e instanceof IllegalStateException)) {
3295                Slog.wtf(TAG, "Activity Manager Crash."
3296                        + " UID:" + Binder.getCallingUid()
3297                        + " PID:" + Binder.getCallingPid()
3298                        + " TRANS:" + code, e);
3299            }
3300            throw e;
3301        }
3302    }
3303
3304    void updateCpuStats() {
3305        final long now = SystemClock.uptimeMillis();
3306        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
3307            return;
3308        }
3309        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
3310            synchronized (mProcessCpuThread) {
3311                mProcessCpuThread.notify();
3312            }
3313        }
3314    }
3315
3316    void updateCpuStatsNow() {
3317        synchronized (mProcessCpuTracker) {
3318            mProcessCpuMutexFree.set(false);
3319            final long now = SystemClock.uptimeMillis();
3320            boolean haveNewCpuStats = false;
3321
3322            if (MONITOR_CPU_USAGE &&
3323                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
3324                mLastCpuTime.set(now);
3325                mProcessCpuTracker.update();
3326                if (mProcessCpuTracker.hasGoodLastStats()) {
3327                    haveNewCpuStats = true;
3328                    //Slog.i(TAG, mProcessCpu.printCurrentState());
3329                    //Slog.i(TAG, "Total CPU usage: "
3330                    //        + mProcessCpu.getTotalCpuPercent() + "%");
3331
3332                    // Slog the cpu usage if the property is set.
3333                    if ("true".equals(SystemProperties.get("events.cpu"))) {
3334                        int user = mProcessCpuTracker.getLastUserTime();
3335                        int system = mProcessCpuTracker.getLastSystemTime();
3336                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
3337                        int irq = mProcessCpuTracker.getLastIrqTime();
3338                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
3339                        int idle = mProcessCpuTracker.getLastIdleTime();
3340
3341                        int total = user + system + iowait + irq + softIrq + idle;
3342                        if (total == 0) total = 1;
3343
3344                        EventLog.writeEvent(EventLogTags.CPU,
3345                                ((user+system+iowait+irq+softIrq) * 100) / total,
3346                                (user * 100) / total,
3347                                (system * 100) / total,
3348                                (iowait * 100) / total,
3349                                (irq * 100) / total,
3350                                (softIrq * 100) / total);
3351                    }
3352                }
3353            }
3354
3355            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3356            synchronized(bstats) {
3357                synchronized(mPidsSelfLocked) {
3358                    if (haveNewCpuStats) {
3359                        if (bstats.startAddingCpuLocked()) {
3360                            int totalUTime = 0;
3361                            int totalSTime = 0;
3362                            final int N = mProcessCpuTracker.countStats();
3363                            for (int i=0; i<N; i++) {
3364                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3365                                if (!st.working) {
3366                                    continue;
3367                                }
3368                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3369                                totalUTime += st.rel_utime;
3370                                totalSTime += st.rel_stime;
3371                                if (pr != null) {
3372                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3373                                    if (ps == null || !ps.isActive()) {
3374                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3375                                                pr.info.uid, pr.processName);
3376                                    }
3377                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3378                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3379                                    if (pr.lastCpuTime == 0) {
3380                                        pr.lastCpuTime = pr.curCpuTime;
3381                                    }
3382                                } else {
3383                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3384                                    if (ps == null || !ps.isActive()) {
3385                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3386                                                bstats.mapUid(st.uid), st.name);
3387                                    }
3388                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3389                                }
3390                            }
3391                            final int userTime = mProcessCpuTracker.getLastUserTime();
3392                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3393                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3394                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3395                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3396                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3397                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3398                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3399                        }
3400                    }
3401                }
3402
3403                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3404                    mLastWriteTime = now;
3405                    mBatteryStatsService.scheduleWriteToDisk();
3406                }
3407            }
3408        }
3409    }
3410
3411    @Override
3412    public void batteryNeedsCpuUpdate() {
3413        updateCpuStatsNow();
3414    }
3415
3416    @Override
3417    public void batteryPowerChanged(boolean onBattery) {
3418        // When plugging in, update the CPU stats first before changing
3419        // the plug state.
3420        updateCpuStatsNow();
3421        synchronized (this) {
3422            synchronized(mPidsSelfLocked) {
3423                mOnBattery = DEBUG_POWER ? true : onBattery;
3424            }
3425        }
3426    }
3427
3428    @Override
3429    public void batteryStatsReset() {
3430        BinderCallsStatsService.reset();
3431    }
3432
3433    @Override
3434    public void batterySendBroadcast(Intent intent) {
3435        synchronized (this) {
3436            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3437                    OP_NONE, null, false, false,
3438                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3439        }
3440    }
3441
3442    /**
3443     * Initialize the application bind args. These are passed to each
3444     * process when the bindApplication() IPC is sent to the process. They're
3445     * lazily setup to make sure the services are running when they're asked for.
3446     */
3447    private ArrayMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3448        // Isolated processes won't get this optimization, so that we don't
3449        // violate the rules about which services they have access to.
3450        if (isolated) {
3451            if (mIsolatedAppBindArgs == null) {
3452                mIsolatedAppBindArgs = new ArrayMap<>(1);
3453                addServiceToMap(mIsolatedAppBindArgs, "package");
3454            }
3455            return mIsolatedAppBindArgs;
3456        }
3457
3458        if (mAppBindArgs == null) {
3459            mAppBindArgs = new ArrayMap<>();
3460
3461            // Add common services.
3462            // IMPORTANT: Before adding services here, make sure ephemeral apps can access them too.
3463            // Enable the check in ApplicationThread.bindApplication() to make sure.
3464            addServiceToMap(mAppBindArgs, "package");
3465            addServiceToMap(mAppBindArgs, Context.WINDOW_SERVICE);
3466            addServiceToMap(mAppBindArgs, Context.ALARM_SERVICE);
3467            addServiceToMap(mAppBindArgs, Context.DISPLAY_SERVICE);
3468            addServiceToMap(mAppBindArgs, Context.NETWORKMANAGEMENT_SERVICE);
3469            addServiceToMap(mAppBindArgs, Context.CONNECTIVITY_SERVICE);
3470            addServiceToMap(mAppBindArgs, Context.ACCESSIBILITY_SERVICE);
3471            addServiceToMap(mAppBindArgs, Context.INPUT_METHOD_SERVICE);
3472            addServiceToMap(mAppBindArgs, Context.INPUT_SERVICE);
3473            addServiceToMap(mAppBindArgs, "graphicsstats");
3474            addServiceToMap(mAppBindArgs, Context.APP_OPS_SERVICE);
3475            addServiceToMap(mAppBindArgs, "content");
3476            addServiceToMap(mAppBindArgs, Context.JOB_SCHEDULER_SERVICE);
3477            addServiceToMap(mAppBindArgs, Context.NOTIFICATION_SERVICE);
3478            addServiceToMap(mAppBindArgs, Context.VIBRATOR_SERVICE);
3479            addServiceToMap(mAppBindArgs, Context.ACCOUNT_SERVICE);
3480            addServiceToMap(mAppBindArgs, Context.POWER_SERVICE);
3481            addServiceToMap(mAppBindArgs, Context.USER_SERVICE);
3482            addServiceToMap(mAppBindArgs, "mount");
3483        }
3484        return mAppBindArgs;
3485    }
3486
3487    private static void addServiceToMap(ArrayMap<String, IBinder> map, String name) {
3488        final IBinder service = ServiceManager.getService(name);
3489        if (service != null) {
3490            map.put(name, service);
3491            if (false) {
3492                Log.i(TAG, "Adding " + name + " to the pre-loaded service cache.");
3493            }
3494        }
3495    }
3496
3497    /**
3498     * Update AMS states when an activity is resumed. This should only be called by
3499     * {@link ActivityStack#onActivityStateChanged(ActivityRecord, ActivityState, String)} when an
3500     * activity is resumed.
3501     */
3502    @GuardedBy("this")
3503    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3504        final TaskRecord task = r.getTask();
3505        if (task.isActivityTypeStandard()) {
3506            if (mCurAppTimeTracker != r.appTimeTracker) {
3507                // We are switching app tracking.  Complete the current one.
3508                if (mCurAppTimeTracker != null) {
3509                    mCurAppTimeTracker.stop();
3510                    mHandler.obtainMessage(
3511                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3512                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3513                    mCurAppTimeTracker = null;
3514                }
3515                if (r.appTimeTracker != null) {
3516                    mCurAppTimeTracker = r.appTimeTracker;
3517                    startTimeTrackingFocusedActivityLocked();
3518                }
3519            } else {
3520                startTimeTrackingFocusedActivityLocked();
3521            }
3522        } else {
3523            r.appTimeTracker = null;
3524        }
3525        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3526        // TODO: Probably not, because we don't want to resume voice on switching
3527        // back to this activity
3528        if (task.voiceInteractor != null) {
3529            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3530        } else {
3531            finishRunningVoiceLocked();
3532
3533            if (mLastResumedActivity != null) {
3534                final IVoiceInteractionSession session;
3535
3536                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3537                if (lastResumedActivityTask != null
3538                        && lastResumedActivityTask.voiceSession != null) {
3539                    session = lastResumedActivityTask.voiceSession;
3540                } else {
3541                    session = mLastResumedActivity.voiceSession;
3542                }
3543
3544                if (session != null) {
3545                    // We had been in a voice interaction session, but now focused has
3546                    // move to something different.  Just finish the session, we can't
3547                    // return to it and retain the proper state and synchronization with
3548                    // the voice interaction service.
3549                    finishVoiceTask(session);
3550                }
3551            }
3552        }
3553
3554        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3555            mUserController.sendForegroundProfileChanged(r.userId);
3556        }
3557        updateResumedAppTrace(r);
3558        mLastResumedActivity = r;
3559
3560        mWindowManager.setFocusedApp(r.appToken, true);
3561
3562        applyUpdateLockStateLocked(r);
3563        applyUpdateVrModeLocked(r);
3564
3565        EventLogTags.writeAmSetResumedActivity(
3566                r == null ? -1 : r.userId,
3567                r == null ? "NULL" : r.shortComponentName,
3568                reason);
3569    }
3570
3571    private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
3572        if (mTracedResumedActivity != null) {
3573            Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
3574                    constructResumedTraceName(mTracedResumedActivity.packageName), 0);
3575        }
3576        if (resumed != null) {
3577            Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
3578                    constructResumedTraceName(resumed.packageName), 0);
3579        }
3580        mTracedResumedActivity = resumed;
3581    }
3582
3583    private String constructResumedTraceName(String packageName) {
3584        return "focused app: " + packageName;
3585    }
3586
3587    @Override
3588    public void setFocusedStack(int stackId) {
3589        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3590        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3591        final long callingId = Binder.clearCallingIdentity();
3592        try {
3593            synchronized (this) {
3594                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3595                if (stack == null) {
3596                    Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
3597                    return;
3598                }
3599                final ActivityRecord r = stack.topRunningActivityLocked();
3600                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3601                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3602                }
3603            }
3604        } finally {
3605            Binder.restoreCallingIdentity(callingId);
3606        }
3607    }
3608
3609    @Override
3610    public void setFocusedTask(int taskId) {
3611        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3612        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3613        final long callingId = Binder.clearCallingIdentity();
3614        try {
3615            synchronized (this) {
3616                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3617                if (task == null) {
3618                    return;
3619                }
3620                final ActivityRecord r = task.topRunningActivityLocked();
3621                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3622                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3623                }
3624            }
3625        } finally {
3626            Binder.restoreCallingIdentity(callingId);
3627        }
3628    }
3629
3630    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3631    @Override
3632    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3633        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3634                "registerTaskStackListener()");
3635        mTaskChangeNotificationController.registerTaskStackListener(listener);
3636    }
3637
3638    /**
3639     * Unregister a task stack listener so that it stops receiving callbacks.
3640     */
3641    @Override
3642    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3643        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3644                "unregisterTaskStackListener()");
3645         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3646     }
3647
3648    @Override
3649    public void notifyActivityDrawn(IBinder token) {
3650        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3651        synchronized (this) {
3652            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3653            if (r != null) {
3654                r.getStack().notifyActivityDrawnLocked(r);
3655            }
3656        }
3657    }
3658
3659    final void applyUpdateLockStateLocked(ActivityRecord r) {
3660        // Modifications to the UpdateLock state are done on our handler, outside
3661        // the activity manager's locks.  The new state is determined based on the
3662        // state *now* of the relevant activity record.  The object is passed to
3663        // the handler solely for logging detail, not to be consulted/modified.
3664        final boolean nextState = r != null && r.immersive;
3665        mHandler.sendMessage(
3666                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3667    }
3668
3669    final void applyUpdateVrModeLocked(ActivityRecord r) {
3670        // VR apps are expected to run in a main display. If an app is turning on VR for
3671        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3672        // fullscreen stack before enabling VR Mode.
3673        // TODO: The goal of this code is to keep the VR app on the main display. When the
3674        // stack implementation changes in the future, keep in mind that the use of the fullscreen
3675        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3676        // option would be a better choice here.
3677        if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3678            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3679                    + " to main stack for VR");
3680            final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3681                    WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3682            moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3683        }
3684        mHandler.sendMessage(
3685                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3686    }
3687
3688    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3689        Message msg = Message.obtain();
3690        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3691        msg.obj = r.getTask().askedCompatMode ? null : r;
3692        mUiHandler.sendMessage(msg);
3693    }
3694
3695    final AppWarnings getAppWarningsLocked() {
3696        return mAppWarnings;
3697    }
3698
3699    /**
3700     * Shows app warning dialogs, if necessary.
3701     *
3702     * @param r activity record for which the warnings may be displayed
3703     */
3704    final void showAppWarningsIfNeededLocked(ActivityRecord r) {
3705        mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
3706        mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
3707        mAppWarnings.showDeprecatedTargetDialogIfNeeded(r);
3708    }
3709
3710    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3711            String what, Object obj, ProcessRecord srcApp) {
3712        app.lastActivityTime = now;
3713
3714        if (app.activities.size() > 0 || app.recentTasks.size() > 0) {
3715            // Don't want to touch dependent processes that are hosting activities.
3716            return index;
3717        }
3718
3719        int lrui = mLruProcesses.lastIndexOf(app);
3720        if (lrui < 0) {
3721            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3722                    + what + " " + obj + " from " + srcApp);
3723            return index;
3724        }
3725
3726        if (lrui >= index) {
3727            // Don't want to cause this to move dependent processes *back* in the
3728            // list as if they were less frequently used.
3729            return index;
3730        }
3731
3732        if (lrui >= mLruProcessActivityStart) {
3733            // Don't want to touch dependent processes that are hosting activities.
3734            return index;
3735        }
3736
3737        mLruProcesses.remove(lrui);
3738        if (index > 0) {
3739            index--;
3740        }
3741        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3742                + " in LRU list: " + app);
3743        mLruProcesses.add(index, app);
3744        return index;
3745    }
3746
3747    static void killProcessGroup(int uid, int pid) {
3748        if (sKillHandler != null) {
3749            sKillHandler.sendMessage(
3750                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3751        } else {
3752            Slog.w(TAG, "Asked to kill process group before system bringup!");
3753            Process.killProcessGroup(uid, pid);
3754        }
3755    }
3756
3757    final void removeLruProcessLocked(ProcessRecord app) {
3758        int lrui = mLruProcesses.lastIndexOf(app);
3759        if (lrui >= 0) {
3760            if (!app.killed) {
3761                if (app.persistent) {
3762                    Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
3763                } else {
3764                    Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3765                    if (app.pid > 0) {
3766                        killProcessQuiet(app.pid);
3767                        killProcessGroup(app.uid, app.pid);
3768                    } else {
3769                        app.pendingStart = false;
3770                    }
3771                }
3772            }
3773            if (lrui <= mLruProcessActivityStart) {
3774                mLruProcessActivityStart--;
3775            }
3776            if (lrui <= mLruProcessServiceStart) {
3777                mLruProcessServiceStart--;
3778            }
3779            mLruProcesses.remove(lrui);
3780        }
3781    }
3782
3783    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3784            ProcessRecord client) {
3785        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3786                || app.treatLikeActivity || app.recentTasks.size() > 0;
3787        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3788        if (!activityChange && hasActivity) {
3789            // The process has activities, so we are only allowing activity-based adjustments
3790            // to move it.  It should be kept in the front of the list with other
3791            // processes that have activities, and we don't want those to change their
3792            // order except due to activity operations.
3793            return;
3794        }
3795
3796        mLruSeq++;
3797        final long now = SystemClock.uptimeMillis();
3798        app.lastActivityTime = now;
3799
3800        // First a quick reject: if the app is already at the position we will
3801        // put it, then there is nothing to do.
3802        if (hasActivity) {
3803            final int N = mLruProcesses.size();
3804            if (N > 0 && mLruProcesses.get(N-1) == app) {
3805                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3806                return;
3807            }
3808        } else {
3809            if (mLruProcessServiceStart > 0
3810                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3811                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3812                return;
3813            }
3814        }
3815
3816        int lrui = mLruProcesses.lastIndexOf(app);
3817
3818        if (app.persistent && lrui >= 0) {
3819            // We don't care about the position of persistent processes, as long as
3820            // they are in the list.
3821            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3822            return;
3823        }
3824
3825        /* In progress: compute new position first, so we can avoid doing work
3826           if the process is not actually going to move.  Not yet working.
3827        int addIndex;
3828        int nextIndex;
3829        boolean inActivity = false, inService = false;
3830        if (hasActivity) {
3831            // Process has activities, put it at the very tipsy-top.
3832            addIndex = mLruProcesses.size();
3833            nextIndex = mLruProcessServiceStart;
3834            inActivity = true;
3835        } else if (hasService) {
3836            // Process has services, put it at the top of the service list.
3837            addIndex = mLruProcessActivityStart;
3838            nextIndex = mLruProcessServiceStart;
3839            inActivity = true;
3840            inService = true;
3841        } else  {
3842            // Process not otherwise of interest, it goes to the top of the non-service area.
3843            addIndex = mLruProcessServiceStart;
3844            if (client != null) {
3845                int clientIndex = mLruProcesses.lastIndexOf(client);
3846                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3847                        + app);
3848                if (clientIndex >= 0 && addIndex > clientIndex) {
3849                    addIndex = clientIndex;
3850                }
3851            }
3852            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3853        }
3854
3855        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3856                + mLruProcessActivityStart + "): " + app);
3857        */
3858
3859        if (lrui >= 0) {
3860            if (lrui < mLruProcessActivityStart) {
3861                mLruProcessActivityStart--;
3862            }
3863            if (lrui < mLruProcessServiceStart) {
3864                mLruProcessServiceStart--;
3865            }
3866            /*
3867            if (addIndex > lrui) {
3868                addIndex--;
3869            }
3870            if (nextIndex > lrui) {
3871                nextIndex--;
3872            }
3873            */
3874            mLruProcesses.remove(lrui);
3875        }
3876
3877        /*
3878        mLruProcesses.add(addIndex, app);
3879        if (inActivity) {
3880            mLruProcessActivityStart++;
3881        }
3882        if (inService) {
3883            mLruProcessActivityStart++;
3884        }
3885        */
3886
3887        int nextIndex;
3888        if (hasActivity) {
3889            final int N = mLruProcesses.size();
3890            if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
3891                    && mLruProcessActivityStart < (N - 1)) {
3892                // Process doesn't have activities, but has clients with
3893                // activities...  move it up, but one below the top (the top
3894                // should always have a real activity).
3895                if (DEBUG_LRU) Slog.d(TAG_LRU,
3896                        "Adding to second-top of LRU activity list: " + app);
3897                mLruProcesses.add(N - 1, app);
3898                // To keep it from spamming the LRU list (by making a bunch of clients),
3899                // we will push down any other entries owned by the app.
3900                final int uid = app.info.uid;
3901                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3902                    ProcessRecord subProc = mLruProcesses.get(i);
3903                    if (subProc.info.uid == uid) {
3904                        // We want to push this one down the list.  If the process after
3905                        // it is for the same uid, however, don't do so, because we don't
3906                        // want them internally to be re-ordered.
3907                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3908                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3909                                    "Pushing uid " + uid + " swapping at " + i + ": "
3910                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3911                            ProcessRecord tmp = mLruProcesses.get(i);
3912                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3913                            mLruProcesses.set(i - 1, tmp);
3914                            i--;
3915                        }
3916                    } else {
3917                        // A gap, we can stop here.
3918                        break;
3919                    }
3920                }
3921            } else {
3922                // Process has activities, put it at the very tipsy-top.
3923                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3924                mLruProcesses.add(app);
3925            }
3926            nextIndex = mLruProcessServiceStart;
3927        } else if (hasService) {
3928            // Process has services, put it at the top of the service list.
3929            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3930            mLruProcesses.add(mLruProcessActivityStart, app);
3931            nextIndex = mLruProcessServiceStart;
3932            mLruProcessActivityStart++;
3933        } else  {
3934            // Process not otherwise of interest, it goes to the top of the non-service area.
3935            int index = mLruProcessServiceStart;
3936            if (client != null) {
3937                // If there is a client, don't allow the process to be moved up higher
3938                // in the list than that client.
3939                int clientIndex = mLruProcesses.lastIndexOf(client);
3940                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3941                        + " when updating " + app);
3942                if (clientIndex <= lrui) {
3943                    // Don't allow the client index restriction to push it down farther in the
3944                    // list than it already is.
3945                    clientIndex = lrui;
3946                }
3947                if (clientIndex >= 0 && index > clientIndex) {
3948                    index = clientIndex;
3949                }
3950            }
3951            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3952            mLruProcesses.add(index, app);
3953            nextIndex = index-1;
3954            mLruProcessActivityStart++;
3955            mLruProcessServiceStart++;
3956        }
3957
3958        // If the app is currently using a content provider or service,
3959        // bump those processes as well.
3960        for (int j=app.connections.size()-1; j>=0; j--) {
3961            ConnectionRecord cr = app.connections.valueAt(j);
3962            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3963                    && cr.binding.service.app != null
3964                    && cr.binding.service.app.lruSeq != mLruSeq
3965                    && !cr.binding.service.app.persistent) {
3966                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3967                        "service connection", cr, app);
3968            }
3969        }
3970        for (int j=app.conProviders.size()-1; j>=0; j--) {
3971            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3972            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3973                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3974                        "provider reference", cpr, app);
3975            }
3976        }
3977    }
3978
3979    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3980        if (uid == SYSTEM_UID) {
3981            // The system gets to run in any process.  If there are multiple
3982            // processes with the same uid, just pick the first (this
3983            // should never happen).
3984            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3985            if (procs == null) return null;
3986            final int procCount = procs.size();
3987            for (int i = 0; i < procCount; i++) {
3988                final int procUid = procs.keyAt(i);
3989                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3990                    // Don't use an app process or different user process for system component.
3991                    continue;
3992                }
3993                return procs.valueAt(i);
3994            }
3995        }
3996        ProcessRecord proc = mProcessNames.get(processName, uid);
3997        if (false && proc != null && !keepIfLarge
3998                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3999                && proc.lastCachedPss >= 4000) {
4000            // Turn this condition on to cause killing to happen regularly, for testing.
4001            if (proc.baseProcessTracker != null) {
4002                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
4003            }
4004            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
4005        } else if (proc != null && !keepIfLarge
4006                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
4007                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
4008            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
4009            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
4010                if (proc.baseProcessTracker != null) {
4011                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
4012                }
4013                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
4014            }
4015        }
4016        return proc;
4017    }
4018
4019    void notifyPackageUse(String packageName, int reason) {
4020        synchronized(this) {
4021            getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
4022        }
4023    }
4024
4025    boolean isNextTransitionForward() {
4026        int transit = mWindowManager.getPendingAppTransition();
4027        return transit == TRANSIT_ACTIVITY_OPEN
4028                || transit == TRANSIT_TASK_OPEN
4029                || transit == TRANSIT_TASK_TO_FRONT;
4030    }
4031
4032    boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
4033            String processName, String abiOverride, int uid, Runnable crashHandler) {
4034        synchronized(this) {
4035            ApplicationInfo info = new ApplicationInfo();
4036            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
4037            // For isolated processes, the former contains the parent's uid and the latter the
4038            // actual uid of the isolated process.
4039            // In the special case introduced by this method (which is, starting an isolated
4040            // process directly from the SystemServer without an actual parent app process) the
4041            // closest thing to a parent's uid is SYSTEM_UID.
4042            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
4043            // the |isolated| logic in the ProcessRecord constructor.
4044            info.uid = SYSTEM_UID;
4045            info.processName = processName;
4046            info.className = entryPoint;
4047            info.packageName = "android";
4048            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
4049            info.targetSdkVersion = Build.VERSION.SDK_INT;
4050            ProcessRecord proc = startProcessLocked(processName, info /* info */,
4051                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
4052                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
4053                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
4054                    crashHandler);
4055            return proc != null;
4056        }
4057    }
4058
4059    @GuardedBy("this")
4060    final ProcessRecord startProcessLocked(String processName,
4061            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
4062            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
4063            boolean isolated, boolean keepIfLarge) {
4064        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
4065                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
4066                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
4067                null /* crashHandler */);
4068    }
4069
4070    @GuardedBy("this")
4071    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
4072            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
4073            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
4074            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
4075        long startTime = SystemClock.elapsedRealtime();
4076        ProcessRecord app;
4077        if (!isolated) {
4078            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
4079            checkTime(startTime, "startProcess: after getProcessRecord");
4080
4081            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
4082                // If we are in the background, then check to see if this process
4083                // is bad.  If so, we will just silently fail.
4084                if (mAppErrors.isBadProcessLocked(info)) {
4085                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
4086                            + "/" + info.processName);
4087                    return null;
4088                }
4089            } else {
4090                // When the user is explicitly starting a process, then clear its
4091                // crash count so that we won't make it bad until they see at
4092                // least one crash dialog again, and make the process good again
4093                // if it had been bad.
4094                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
4095                        + "/" + info.processName);
4096                mAppErrors.resetProcessCrashTimeLocked(info);
4097                if (mAppErrors.isBadProcessLocked(info)) {
4098                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
4099                            UserHandle.getUserId(info.uid), info.uid,
4100                            info.processName);
4101                    mAppErrors.clearBadProcessLocked(info);
4102                    if (app != null) {
4103                        app.bad = false;
4104                    }
4105                }
4106            }
4107        } else {
4108            // If this is an isolated process, it can't re-use an existing process.
4109            app = null;
4110        }
4111
4112        // We don't have to do anything more if:
4113        // (1) There is an existing application record; and
4114        // (2) The caller doesn't think it is dead, OR there is no thread
4115        //     object attached to it so we know it couldn't have crashed; and
4116        // (3) There is a pid assigned to it, so it is either starting or
4117        //     already running.
4118        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
4119                + " app=" + app + " knownToBeDead=" + knownToBeDead
4120                + " thread=" + (app != null ? app.thread : null)
4121                + " pid=" + (app != null ? app.pid : -1));
4122        if (app != null && app.pid > 0) {
4123            if ((!knownToBeDead && !app.killed) || app.thread == null) {
4124                // We already have the app running, or are waiting for it to
4125                // come up (we have a pid but not yet its thread), so keep it.
4126                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
4127                // If this is a new package in the process, add the package to the list
4128                app.addPackage(info.packageName, info.versionCode, mProcessStats);
4129                checkTime(startTime, "startProcess: done, added package to proc");
4130                return app;
4131            }
4132
4133            // An application record is attached to a previous process,
4134            // clean it up now.
4135            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
4136            checkTime(startTime, "startProcess: bad proc running, killing");
4137            killProcessGroup(app.uid, app.pid);
4138            handleAppDiedLocked(app, true, true);
4139            checkTime(startTime, "startProcess: done killing old proc");
4140        }
4141
4142        String hostingNameStr = hostingName != null
4143                ? hostingName.flattenToShortString() : null;
4144
4145        if (app == null) {
4146            checkTime(startTime, "startProcess: creating new process record");
4147            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
4148            if (app == null) {
4149                Slog.w(TAG, "Failed making new process record for "
4150                        + processName + "/" + info.uid + " isolated=" + isolated);
4151                return null;
4152            }
4153            app.crashHandler = crashHandler;
4154            app.isolatedEntryPoint = entryPoint;
4155            app.isolatedEntryPointArgs = entryPointArgs;
4156            checkTime(startTime, "startProcess: done creating new process record");
4157        } else {
4158            // If this is a new package in the process, add the package to the list
4159            app.addPackage(info.packageName, info.versionCode, mProcessStats);
4160            checkTime(startTime, "startProcess: added package to existing proc");
4161        }
4162
4163        // If the system is not ready yet, then hold off on starting this
4164        // process until it is.
4165        if (!mProcessesReady
4166                && !isAllowedWhileBooting(info)
4167                && !allowWhileBooting) {
4168            if (!mProcessesOnHold.contains(app)) {
4169                mProcessesOnHold.add(app);
4170            }
4171            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
4172                    "System not ready, putting on hold: " + app);
4173            checkTime(startTime, "startProcess: returning with proc on hold");
4174            return app;
4175        }
4176
4177        checkTime(startTime, "startProcess: stepping in to startProcess");
4178        final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
4179        checkTime(startTime, "startProcess: done starting proc!");
4180        return success ? app : null;
4181    }
4182
4183    boolean isAllowedWhileBooting(ApplicationInfo ai) {
4184        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
4185    }
4186
4187    @GuardedBy("this")
4188    private final void startProcessLocked(ProcessRecord app,
4189            String hostingType, String hostingNameStr) {
4190        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
4191    }
4192
4193    @GuardedBy("this")
4194    private final boolean startProcessLocked(ProcessRecord app,
4195            String hostingType, String hostingNameStr, String abiOverride) {
4196        return startProcessLocked(app, hostingType, hostingNameStr,
4197                false /* disableHiddenApiChecks */, abiOverride);
4198    }
4199
4200    /**
4201     * @return {@code true} if process start is successful, false otherwise.
4202     */
4203    @GuardedBy("this")
4204    private final boolean startProcessLocked(ProcessRecord app, String hostingType,
4205            String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
4206        if (app.pendingStart) {
4207            return true;
4208        }
4209        long startTime = SystemClock.elapsedRealtime();
4210        if (app.pid > 0 && app.pid != MY_PID) {
4211            checkTime(startTime, "startProcess: removing from pids map");
4212            synchronized (mPidsSelfLocked) {
4213                mPidsSelfLocked.remove(app.pid);
4214                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4215            }
4216            checkTime(startTime, "startProcess: done removing from pids map");
4217            app.setPid(0);
4218        }
4219
4220        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
4221                "startProcessLocked removing on hold: " + app);
4222        mProcessesOnHold.remove(app);
4223
4224        checkTime(startTime, "startProcess: starting to update cpu stats");
4225        updateCpuStats();
4226        checkTime(startTime, "startProcess: done updating cpu stats");
4227
4228        try {
4229            try {
4230                final int userId = UserHandle.getUserId(app.uid);
4231                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
4232            } catch (RemoteException e) {
4233                throw e.rethrowAsRuntimeException();
4234            }
4235
4236            int uid = app.uid;
4237            int[] gids = null;
4238            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
4239            if (!app.isolated) {
4240                int[] permGids = null;
4241                try {
4242                    checkTime(startTime, "startProcess: getting gids from package manager");
4243                    final IPackageManager pm = AppGlobals.getPackageManager();
4244                    permGids = pm.getPackageGids(app.info.packageName,
4245                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
4246                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
4247                            StorageManagerInternal.class);
4248                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
4249                            app.info.packageName);
4250                } catch (RemoteException e) {
4251                    throw e.rethrowAsRuntimeException();
4252                }
4253
4254                /*
4255                 * Add shared application and profile GIDs so applications can share some
4256                 * resources like shared libraries and access user-wide resources
4257                 */
4258                if (ArrayUtils.isEmpty(permGids)) {
4259                    gids = new int[3];
4260                } else {
4261                    gids = new int[permGids.length + 3];
4262                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
4263                }
4264                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
4265                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
4266                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
4267
4268                // Replace any invalid GIDs
4269                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
4270                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
4271            }
4272            checkTime(startTime, "startProcess: building args");
4273            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
4274                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4275                        && mTopComponent != null
4276                        && app.processName.equals(mTopComponent.getPackageName())) {
4277                    uid = 0;
4278                }
4279                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
4280                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
4281                    uid = 0;
4282                }
4283            }
4284            int runtimeFlags = 0;
4285            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4286                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
4287                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
4288                // Also turn on CheckJNI for debuggable apps. It's quite
4289                // awkward to turn on otherwise.
4290                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4291            }
4292            // Run the app in safe mode if its manifest requests so or the
4293            // system is booted in safe mode.
4294            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
4295                mSafeMode == true) {
4296                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
4297            }
4298            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
4299                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4300            }
4301            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
4302            if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
4303                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
4304            }
4305            String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
4306            if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
4307                runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
4308            }
4309            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
4310                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
4311            }
4312            if ("1".equals(SystemProperties.get("debug.assert"))) {
4313                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
4314            }
4315            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
4316                // Enable all debug flags required by the native debugger.
4317                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
4318                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
4319                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
4320                mNativeDebuggingApp = null;
4321            }
4322
4323            if (app.info.isPrivilegedApp() &&
4324                    DexManager.isPackageSelectedToRunOob(app.pkgList.keySet())) {
4325                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
4326            }
4327
4328            if (!disableHiddenApiChecks && !mHiddenApiBlacklist.isDisabled()) {
4329                app.info.maybeUpdateHiddenApiEnforcementPolicy(
4330                        mHiddenApiBlacklist.getPolicyForPrePApps(),
4331                        mHiddenApiBlacklist.getPolicyForPApps());
4332                @HiddenApiEnforcementPolicy int policy =
4333                        app.info.getHiddenApiEnforcementPolicy();
4334                int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
4335                if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
4336                    throw new IllegalStateException("Invalid API policy: " + policy);
4337                }
4338                runtimeFlags |= policyBits;
4339            }
4340
4341            String invokeWith = null;
4342            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4343                // Debuggable apps may include a wrapper script with their library directory.
4344                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
4345                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4346                try {
4347                    if (new File(wrapperFileName).exists()) {
4348                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
4349                    }
4350                } finally {
4351                    StrictMode.setThreadPolicy(oldPolicy);
4352                }
4353            }
4354
4355            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
4356            if (requiredAbi == null) {
4357                requiredAbi = Build.SUPPORTED_ABIS[0];
4358            }
4359
4360            String instructionSet = null;
4361            if (app.info.primaryCpuAbi != null) {
4362                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
4363            }
4364
4365            app.gids = gids;
4366            app.requiredAbi = requiredAbi;
4367            app.instructionSet = instructionSet;
4368
4369            // the per-user SELinux context must be set
4370            if (TextUtils.isEmpty(app.info.seInfoUser)) {
4371                Slog.wtf(TAG, "SELinux tag not defined",
4372                        new IllegalStateException("SELinux tag not defined for "
4373                        + app.info.packageName + " (uid " + app.uid + ")"));
4374            }
4375            final String seInfo = app.info.seInfo
4376                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
4377            // Start the process.  It will either succeed and return a result containing
4378            // the PID of the new process, or else throw a RuntimeException.
4379            final String entryPoint = "android.app.ActivityThread";
4380
4381            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
4382                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
4383                    startTime);
4384        } catch (RuntimeException e) {
4385            Slog.e(TAG, "Failure starting process " + app.processName, e);
4386
4387            // Something went very wrong while trying to start this process; one
4388            // common case is when the package is frozen due to an active
4389            // upgrade. To recover, clean up any active bookkeeping related to
4390            // starting this process. (We already invoked this method once when
4391            // the package was initially frozen through KILL_APPLICATION_MSG, so
4392            // it doesn't hurt to use it again.)
4393            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4394                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4395            return false;
4396        }
4397    }
4398
4399    @GuardedBy("this")
4400    private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
4401            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4402            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4403            long startTime) {
4404        app.pendingStart = true;
4405        app.killedByAm = false;
4406        app.removed = false;
4407        app.killed = false;
4408        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
4409        app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
4410        if (mConstants.FLAG_PROCESS_START_ASYNC) {
4411            if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
4412                    "Posting procStart msg for " + app.toShortString());
4413            mProcStartHandler.post(() -> {
4414                try {
4415                    synchronized (ActivityManagerService.this) {
4416                        final String reason = isProcStartValidLocked(app, startSeq);
4417                        if (reason != null) {
4418                            Slog.w(TAG_PROCESSES, app + " not valid anymore,"
4419                                    + " don't start process, " + reason);
4420                            app.pendingStart = false;
4421                            return;
4422                        }
4423                        app.usingWrapper = invokeWith != null
4424                                || SystemProperties.get("wrap." + app.processName) != null;
4425                        mPendingStarts.put(startSeq, app);
4426                    }
4427                    final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
4428                            app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
4429                            requiredAbi, instructionSet, invokeWith, app.startTime);
4430                    synchronized (ActivityManagerService.this) {
4431                        handleProcessStartedLocked(app, startResult, startSeq);
4432                    }
4433                } catch (RuntimeException e) {
4434                    synchronized (ActivityManagerService.this) {
4435                        Slog.e(TAG, "Failure starting process " + app.processName, e);
4436                        mPendingStarts.remove(startSeq);
4437                        app.pendingStart = false;
4438                        forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4439                                false, false, true, false, false,
4440                                UserHandle.getUserId(app.userId), "start failure");
4441                    }
4442                }
4443            });
4444            return true;
4445        } else {
4446            try {
4447                final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
4448                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
4449                        invokeWith, startTime);
4450                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
4451                        startSeq, false);
4452            } catch (RuntimeException e) {
4453                Slog.e(TAG, "Failure starting process " + app.processName, e);
4454                app.pendingStart = false;
4455                forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4456                        false, false, true, false, false,
4457                        UserHandle.getUserId(app.userId), "start failure");
4458            }
4459            return app.pid > 0;
4460        }
4461    }
4462
4463    private ProcessStartResult startProcess(String hostingType, String entryPoint,
4464            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4465            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4466            long startTime) {
4467        try {
4468            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
4469                    app.processName);
4470            checkTime(startTime, "startProcess: asking zygote to start proc");
4471            final ProcessStartResult startResult;
4472            if (hostingType.equals("webview_service")) {
4473                startResult = startWebView(entryPoint,
4474                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4475                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4476                        app.info.dataDir, null,
4477                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4478            } else {
4479                startResult = Process.start(entryPoint,
4480                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4481                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4482                        app.info.dataDir, invokeWith,
4483                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4484            }
4485            checkTime(startTime, "startProcess: returned from zygote!");
4486            return startResult;
4487        } finally {
4488            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4489        }
4490    }
4491
4492    @GuardedBy("this")
4493    private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
4494        StringBuilder sb = null;
4495        if (app.killedByAm) {
4496            if (sb == null) sb = new StringBuilder();
4497            sb.append("killedByAm=true;");
4498        }
4499        if (mProcessNames.get(app.processName, app.uid) != app) {
4500            if (sb == null) sb = new StringBuilder();
4501            sb.append("No entry in mProcessNames;");
4502        }
4503        if (!app.pendingStart) {
4504            if (sb == null) sb = new StringBuilder();
4505            sb.append("pendingStart=false;");
4506        }
4507        if (app.startSeq > expectedStartSeq) {
4508            if (sb == null) sb = new StringBuilder();
4509            sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
4510        }
4511        return sb == null ? null : sb.toString();
4512    }
4513
4514    @GuardedBy("this")
4515    private boolean handleProcessStartedLocked(ProcessRecord pending,
4516            ProcessStartResult startResult, long expectedStartSeq) {
4517        // Indicates that this process start has been taken care of.
4518        if (mPendingStarts.get(expectedStartSeq) == null) {
4519            if (pending.pid == startResult.pid) {
4520                pending.usingWrapper = startResult.usingWrapper;
4521                // TODO: Update already existing clients of usingWrapper
4522            }
4523            return false;
4524        }
4525        return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
4526                expectedStartSeq, false);
4527    }
4528
4529    @GuardedBy("this")
4530    private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
4531            long expectedStartSeq, boolean procAttached) {
4532        mPendingStarts.remove(expectedStartSeq);
4533        final String reason = isProcStartValidLocked(app, expectedStartSeq);
4534        if (reason != null) {
4535            Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
4536                    + ", " + reason);
4537            app.pendingStart = false;
4538            Process.killProcessQuiet(pid);
4539            Process.killProcessGroup(app.uid, app.pid);
4540            return false;
4541        }
4542        mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
4543        checkTime(app.startTime, "startProcess: done updating battery stats");
4544
4545        EventLog.writeEvent(EventLogTags.AM_PROC_START,
4546                UserHandle.getUserId(app.startUid), pid, app.startUid,
4547                app.processName, app.hostingType,
4548                app.hostingNameStr != null ? app.hostingNameStr : "");
4549
4550        try {
4551            AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
4552                    app.seInfo, app.info.sourceDir, pid);
4553        } catch (RemoteException ex) {
4554            // Ignore
4555        }
4556
4557        if (app.persistent) {
4558            Watchdog.getInstance().processStarted(app.processName, pid);
4559        }
4560
4561        checkTime(app.startTime, "startProcess: building log message");
4562        StringBuilder buf = mStringBuilder;
4563        buf.setLength(0);
4564        buf.append("Start proc ");
4565        buf.append(pid);
4566        buf.append(':');
4567        buf.append(app.processName);
4568        buf.append('/');
4569        UserHandle.formatUid(buf, app.startUid);
4570        if (app.isolatedEntryPoint != null) {
4571            buf.append(" [");
4572            buf.append(app.isolatedEntryPoint);
4573            buf.append("]");
4574        }
4575        buf.append(" for ");
4576        buf.append(app.hostingType);
4577        if (app.hostingNameStr != null) {
4578            buf.append(" ");
4579            buf.append(app.hostingNameStr);
4580        }
4581        reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
4582        app.setPid(pid);
4583        app.usingWrapper = usingWrapper;
4584        app.pendingStart = false;
4585        checkTime(app.startTime, "startProcess: starting to update pids map");
4586        ProcessRecord oldApp;
4587        synchronized (mPidsSelfLocked) {
4588            oldApp = mPidsSelfLocked.get(pid);
4589        }
4590        // If there is already an app occupying that pid that hasn't been cleaned up
4591        if (oldApp != null && !app.isolated) {
4592            // Clean up anything relating to this pid first
4593            Slog.w(TAG, "Reusing pid " + pid
4594                    + " while app is still mapped to it");
4595            cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4596                    true /*replacingPid*/);
4597        }
4598        synchronized (mPidsSelfLocked) {
4599            this.mPidsSelfLocked.put(pid, app);
4600            if (!procAttached) {
4601                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4602                msg.obj = app;
4603                mHandler.sendMessageDelayed(msg, usingWrapper
4604                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4605            }
4606        }
4607        checkTime(app.startTime, "startProcess: done updating pids map");
4608        return true;
4609    }
4610
4611    void updateUsageStats(ActivityRecord component, boolean resumed) {
4612        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4613                "updateUsageStats: comp=" + component + "res=" + resumed);
4614        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4615        StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
4616            component.app.uid, component.realActivity.getPackageName(),
4617            component.realActivity.getShortClassName(), resumed ?
4618                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND :
4619                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND);
4620        if (resumed) {
4621            if (mUsageStatsService != null) {
4622                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4623                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4624
4625            }
4626            synchronized (stats) {
4627                stats.noteActivityResumedLocked(component.app.uid);
4628            }
4629        } else {
4630            if (mUsageStatsService != null) {
4631                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4632                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4633            }
4634            synchronized (stats) {
4635                stats.noteActivityPausedLocked(component.app.uid);
4636            }
4637        }
4638    }
4639
4640    Intent getHomeIntent() {
4641        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4642        intent.setComponent(mTopComponent);
4643        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4644        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4645            intent.addCategory(Intent.CATEGORY_HOME);
4646        }
4647        return intent;
4648    }
4649
4650    boolean startHomeActivityLocked(int userId, String reason) {
4651        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4652                && mTopAction == null) {
4653            // We are running in factory test mode, but unable to find
4654            // the factory test app, so just sit around displaying the
4655            // error message and don't try to start anything.
4656            return false;
4657        }
4658        Intent intent = getHomeIntent();
4659        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4660        if (aInfo != null) {
4661            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4662            // Don't do this if the home app is currently being
4663            // instrumented.
4664            aInfo = new ActivityInfo(aInfo);
4665            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4666            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4667                    aInfo.applicationInfo.uid, true);
4668            if (app == null || app.instr == null) {
4669                intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
4670                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4671                // For ANR debugging to verify if the user activity is the one that actually
4672                // launched.
4673                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4674                mActivityStartController.startHomeActivity(intent, aInfo, myReason);
4675            }
4676        } else {
4677            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4678        }
4679
4680        return true;
4681    }
4682
4683    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4684        ActivityInfo ai = null;
4685        ComponentName comp = intent.getComponent();
4686        try {
4687            if (comp != null) {
4688                // Factory test.
4689                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4690            } else {
4691                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4692                        intent,
4693                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4694                        flags, userId);
4695
4696                if (info != null) {
4697                    ai = info.activityInfo;
4698                }
4699            }
4700        } catch (RemoteException e) {
4701            // ignore
4702        }
4703
4704        return ai;
4705    }
4706
4707    boolean getCheckedForSetup() {
4708        return mCheckedForSetup;
4709    }
4710
4711    void setCheckedForSetup(boolean checked) {
4712        mCheckedForSetup = checked;
4713    }
4714
4715    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4716        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4717    }
4718
4719    void enforceNotIsolatedCaller(String caller) {
4720        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4721            throw new SecurityException("Isolated process not allowed to call " + caller);
4722        }
4723    }
4724
4725    @Override
4726    public int getFrontActivityScreenCompatMode() {
4727        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4728        synchronized (this) {
4729            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4730        }
4731    }
4732
4733    @Override
4734    public void setFrontActivityScreenCompatMode(int mode) {
4735        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4736                "setFrontActivityScreenCompatMode");
4737        synchronized (this) {
4738            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4739        }
4740    }
4741
4742    @Override
4743    public int getPackageScreenCompatMode(String packageName) {
4744        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4745        synchronized (this) {
4746            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4747        }
4748    }
4749
4750    @Override
4751    public void setPackageScreenCompatMode(String packageName, int mode) {
4752        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4753                "setPackageScreenCompatMode");
4754        synchronized (this) {
4755            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4756        }
4757    }
4758
4759    @Override
4760    public boolean getPackageAskScreenCompat(String packageName) {
4761        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4762        synchronized (this) {
4763            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4764        }
4765    }
4766
4767    @Override
4768    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4769        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4770                "setPackageAskScreenCompat");
4771        synchronized (this) {
4772            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4773        }
4774    }
4775
4776    private boolean hasUsageStatsPermission(String callingPackage) {
4777        final int mode = mAppOpsService.noteOperation(AppOpsManager.OP_GET_USAGE_STATS,
4778                Binder.getCallingUid(), callingPackage);
4779        if (mode == AppOpsManager.MODE_DEFAULT) {
4780            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4781                    == PackageManager.PERMISSION_GRANTED;
4782        }
4783        return mode == AppOpsManager.MODE_ALLOWED;
4784    }
4785
4786    @Override
4787    public int getPackageProcessState(String packageName, String callingPackage) {
4788        if (!hasUsageStatsPermission(callingPackage)) {
4789            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4790                    "getPackageProcessState");
4791        }
4792
4793        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4794        synchronized (this) {
4795            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4796                final ProcessRecord proc = mLruProcesses.get(i);
4797                if (procState > proc.setProcState) {
4798                    if (proc.pkgList.containsKey(packageName) ||
4799                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4800                        procState = proc.setProcState;
4801                    }
4802                }
4803            }
4804        }
4805        return procState;
4806    }
4807
4808    @Override
4809    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4810            throws RemoteException {
4811        synchronized (this) {
4812            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4813            if (app == null) {
4814                throw new IllegalArgumentException("Unknown process: " + process);
4815            }
4816            if (app.thread == null) {
4817                throw new IllegalArgumentException("Process has no app thread");
4818            }
4819            if (app.trimMemoryLevel >= level) {
4820                throw new IllegalArgumentException(
4821                        "Unable to set a higher trim level than current level");
4822            }
4823            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4824                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4825                throw new IllegalArgumentException("Unable to set a background trim level "
4826                    + "on a foreground process");
4827            }
4828            app.thread.scheduleTrimMemory(level);
4829            app.trimMemoryLevel = level;
4830            return true;
4831        }
4832    }
4833
4834    private void dispatchProcessesChanged() {
4835        int N;
4836        synchronized (this) {
4837            N = mPendingProcessChanges.size();
4838            if (mActiveProcessChanges.length < N) {
4839                mActiveProcessChanges = new ProcessChangeItem[N];
4840            }
4841            mPendingProcessChanges.toArray(mActiveProcessChanges);
4842            mPendingProcessChanges.clear();
4843            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4844                    "*** Delivering " + N + " process changes");
4845        }
4846
4847        int i = mProcessObservers.beginBroadcast();
4848        while (i > 0) {
4849            i--;
4850            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4851            if (observer != null) {
4852                try {
4853                    for (int j=0; j<N; j++) {
4854                        ProcessChangeItem item = mActiveProcessChanges[j];
4855                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4856                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4857                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4858                                    + item.uid + ": " + item.foregroundActivities);
4859                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4860                                    item.foregroundActivities);
4861                        }
4862                    }
4863                } catch (RemoteException e) {
4864                }
4865            }
4866        }
4867        mProcessObservers.finishBroadcast();
4868
4869        synchronized (this) {
4870            for (int j=0; j<N; j++) {
4871                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4872            }
4873        }
4874    }
4875
4876    private void dispatchProcessDied(int pid, int uid) {
4877        int i = mProcessObservers.beginBroadcast();
4878        while (i > 0) {
4879            i--;
4880            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4881            if (observer != null) {
4882                try {
4883                    observer.onProcessDied(pid, uid);
4884                } catch (RemoteException e) {
4885                }
4886            }
4887        }
4888        mProcessObservers.finishBroadcast();
4889    }
4890
4891    @VisibleForTesting
4892    void dispatchUidsChanged() {
4893        int N;
4894        synchronized (this) {
4895            N = mPendingUidChanges.size();
4896            if (mActiveUidChanges.length < N) {
4897                mActiveUidChanges = new UidRecord.ChangeItem[N];
4898            }
4899            for (int i=0; i<N; i++) {
4900                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4901                mActiveUidChanges[i] = change;
4902                if (change.uidRecord != null) {
4903                    change.uidRecord.pendingChange = null;
4904                    change.uidRecord = null;
4905                }
4906            }
4907            mPendingUidChanges.clear();
4908            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4909                    "*** Delivering " + N + " uid changes");
4910        }
4911
4912        mUidChangeDispatchCount += N;
4913        int i = mUidObservers.beginBroadcast();
4914        while (i > 0) {
4915            i--;
4916            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4917                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4918        }
4919        mUidObservers.finishBroadcast();
4920
4921        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4922            for (int j = 0; j < N; ++j) {
4923                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4924                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4925                    mValidateUids.remove(item.uid);
4926                } else {
4927                    UidRecord validateUid = mValidateUids.get(item.uid);
4928                    if (validateUid == null) {
4929                        validateUid = new UidRecord(item.uid);
4930                        mValidateUids.put(item.uid, validateUid);
4931                    }
4932                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4933                        validateUid.idle = true;
4934                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4935                        validateUid.idle = false;
4936                    }
4937                    validateUid.curProcState = validateUid.setProcState = item.processState;
4938                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4939                }
4940            }
4941        }
4942
4943        synchronized (this) {
4944            for (int j = 0; j < N; j++) {
4945                mAvailUidChanges.add(mActiveUidChanges[j]);
4946            }
4947        }
4948    }
4949
4950    private void dispatchUidsChangedForObserver(IUidObserver observer,
4951            UidObserverRegistration reg, int changesSize) {
4952        if (observer == null) {
4953            return;
4954        }
4955        try {
4956            for (int j = 0; j < changesSize; j++) {
4957                UidRecord.ChangeItem item = mActiveUidChanges[j];
4958                final int change = item.change;
4959                if (change == UidRecord.CHANGE_PROCSTATE &&
4960                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4961                    // No-op common case: no significant change, the observer is not
4962                    // interested in all proc state changes.
4963                    continue;
4964                }
4965                final long start = SystemClock.uptimeMillis();
4966                if ((change & UidRecord.CHANGE_IDLE) != 0) {
4967                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4968                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4969                                "UID idle uid=" + item.uid);
4970                        observer.onUidIdle(item.uid, item.ephemeral);
4971                    }
4972                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4973                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4974                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4975                                "UID active uid=" + item.uid);
4976                        observer.onUidActive(item.uid);
4977                    }
4978                }
4979                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4980                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
4981                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4982                                "UID cached uid=" + item.uid);
4983                        observer.onUidCachedChanged(item.uid, true);
4984                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4985                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4986                                "UID active uid=" + item.uid);
4987                        observer.onUidCachedChanged(item.uid, false);
4988                    }
4989                }
4990                if ((change & UidRecord.CHANGE_GONE) != 0) {
4991                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4992                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4993                                "UID gone uid=" + item.uid);
4994                        observer.onUidGone(item.uid, item.ephemeral);
4995                    }
4996                    if (reg.lastProcStates != null) {
4997                        reg.lastProcStates.delete(item.uid);
4998                    }
4999                } else {
5000                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
5001                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5002                                "UID CHANGED uid=" + item.uid
5003                                        + ": " + item.processState);
5004                        boolean doReport = true;
5005                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
5006                            final int lastState = reg.lastProcStates.get(item.uid,
5007                                    ActivityManager.PROCESS_STATE_UNKNOWN);
5008                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
5009                                final boolean lastAboveCut = lastState <= reg.cutpoint;
5010                                final boolean newAboveCut = item.processState <= reg.cutpoint;
5011                                doReport = lastAboveCut != newAboveCut;
5012                            } else {
5013                                doReport = item.processState
5014                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
5015                            }
5016                        }
5017                        if (doReport) {
5018                            if (reg.lastProcStates != null) {
5019                                reg.lastProcStates.put(item.uid, item.processState);
5020                            }
5021                            observer.onUidStateChanged(item.uid, item.processState,
5022                                    item.procStateSeq);
5023                        }
5024                    }
5025                }
5026                final int duration = (int) (SystemClock.uptimeMillis() - start);
5027                if (reg.mMaxDispatchTime < duration) {
5028                    reg.mMaxDispatchTime = duration;
5029                }
5030                if (duration >= SLOW_UID_OBSERVER_THRESHOLD_MS) {
5031                    reg.mSlowDispatchCount++;
5032                }
5033            }
5034        } catch (RemoteException e) {
5035        }
5036    }
5037
5038    void dispatchOomAdjObserver(String msg) {
5039        OomAdjObserver observer;
5040        synchronized (this) {
5041            observer = mCurOomAdjObserver;
5042        }
5043
5044        if (observer != null) {
5045            observer.onOomAdjMessage(msg);
5046        }
5047    }
5048
5049    void setOomAdjObserver(int uid, OomAdjObserver observer) {
5050        synchronized (this) {
5051            mCurOomAdjUid = uid;
5052            mCurOomAdjObserver = observer;
5053        }
5054    }
5055
5056    void clearOomAdjObserver() {
5057        synchronized (this) {
5058            mCurOomAdjUid = -1;
5059            mCurOomAdjObserver = null;
5060        }
5061    }
5062
5063    void reportOomAdjMessageLocked(String tag, String msg) {
5064        Slog.d(tag, msg);
5065        if (mCurOomAdjObserver != null) {
5066            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
5067        }
5068    }
5069
5070    void reportUidInfoMessageLocked(String tag, String msg, int uid) {
5071        Slog.i(TAG, msg);
5072        if (mCurOomAdjObserver != null && uid == mCurOomAdjUid) {
5073            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
5074        }
5075
5076    }
5077
5078    @Override
5079    public final int startActivity(IApplicationThread caller, String callingPackage,
5080            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5081            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
5082        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
5083                resultWho, requestCode, startFlags, profilerInfo, bOptions,
5084                UserHandle.getCallingUserId());
5085    }
5086
5087    @Override
5088    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
5089            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5090            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
5091        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
5092                resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
5093                true /*validateIncomingUser*/);
5094    }
5095
5096    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
5097            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5098            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
5099            boolean validateIncomingUser) {
5100        enforceNotIsolatedCaller("startActivity");
5101
5102        userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
5103                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
5104
5105        // TODO: Switch to user app stacks here.
5106        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
5107                .setCaller(caller)
5108                .setCallingPackage(callingPackage)
5109                .setResolvedType(resolvedType)
5110                .setResultTo(resultTo)
5111                .setResultWho(resultWho)
5112                .setRequestCode(requestCode)
5113                .setStartFlags(startFlags)
5114                .setProfilerInfo(profilerInfo)
5115                .setActivityOptions(bOptions)
5116                .setMayWait(userId)
5117                .execute();
5118
5119    }
5120
5121    @Override
5122    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
5123            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5124            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
5125            int userId) {
5126
5127        // This is very dangerous -- it allows you to perform a start activity (including
5128        // permission grants) as any app that may launch one of your own activities.  So
5129        // we will only allow this to be done from activities that are part of the core framework,
5130        // and then only when they are running as the system.
5131        final ActivityRecord sourceRecord;
5132        final int targetUid;
5133        final String targetPackage;
5134        final boolean isResolver;
5135        synchronized (this) {
5136            if (resultTo == null) {
5137                throw new SecurityException("Must be called from an activity");
5138            }
5139            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
5140            if (sourceRecord == null) {
5141                throw new SecurityException("Called with bad activity token: " + resultTo);
5142            }
5143            if (!sourceRecord.info.packageName.equals("android")) {
5144                throw new SecurityException(
5145                        "Must be called from an activity that is declared in the android package");
5146            }
5147            if (sourceRecord.app == null) {
5148                throw new SecurityException("Called without a process attached to activity");
5149            }
5150            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
5151                // This is still okay, as long as this activity is running under the
5152                // uid of the original calling activity.
5153                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
5154                    throw new SecurityException(
5155                            "Calling activity in uid " + sourceRecord.app.uid
5156                                    + " must be system uid or original calling uid "
5157                                    + sourceRecord.launchedFromUid);
5158                }
5159            }
5160            if (ignoreTargetSecurity) {
5161                if (intent.getComponent() == null) {
5162                    throw new SecurityException(
5163                            "Component must be specified with ignoreTargetSecurity");
5164                }
5165                if (intent.getSelector() != null) {
5166                    throw new SecurityException(
5167                            "Selector not allowed with ignoreTargetSecurity");
5168                }
5169            }
5170            targetUid = sourceRecord.launchedFromUid;
5171            targetPackage = sourceRecord.launchedFromPackage;
5172            isResolver = sourceRecord.isResolverOrChildActivity();
5173        }
5174
5175        if (userId == UserHandle.USER_NULL) {
5176            userId = UserHandle.getUserId(sourceRecord.app.uid);
5177        }
5178
5179        // TODO: Switch to user app stacks here.
5180        try {
5181            return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
5182                    .setCallingUid(targetUid)
5183                    .setCallingPackage(targetPackage)
5184                    .setResolvedType(resolvedType)
5185                    .setResultTo(resultTo)
5186                    .setResultWho(resultWho)
5187                    .setRequestCode(requestCode)
5188                    .setStartFlags(startFlags)
5189                    .setActivityOptions(bOptions)
5190                    .setMayWait(userId)
5191                    .setIgnoreTargetSecurity(ignoreTargetSecurity)
5192                    .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
5193                    .execute();
5194        } catch (SecurityException e) {
5195            // XXX need to figure out how to propagate to original app.
5196            // A SecurityException here is generally actually a fault of the original
5197            // calling activity (such as a fairly granting permissions), so propagate it
5198            // back to them.
5199            /*
5200            StringBuilder msg = new StringBuilder();
5201            msg.append("While launching");
5202            msg.append(intent.toString());
5203            msg.append(": ");
5204            msg.append(e.getMessage());
5205            */
5206            throw e;
5207        }
5208    }
5209
5210    @Override
5211    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
5212            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5213            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
5214        enforceNotIsolatedCaller("startActivityAndWait");
5215        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5216                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
5217        WaitResult res = new WaitResult();
5218        // TODO: Switch to user app stacks here.
5219        mActivityStartController.obtainStarter(intent, "startActivityAndWait")
5220                .setCaller(caller)
5221                .setCallingPackage(callingPackage)
5222                .setResolvedType(resolvedType)
5223                .setResultTo(resultTo)
5224                .setResultWho(resultWho)
5225                .setRequestCode(requestCode)
5226                .setStartFlags(startFlags)
5227                .setActivityOptions(bOptions)
5228                .setMayWait(userId)
5229                .setProfilerInfo(profilerInfo)
5230                .setWaitResult(res)
5231                .execute();
5232        return res;
5233    }
5234
5235    @Override
5236    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
5237            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5238            int startFlags, Configuration config, Bundle bOptions, int userId) {
5239        enforceNotIsolatedCaller("startActivityWithConfig");
5240        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5241                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
5242        // TODO: Switch to user app stacks here.
5243        return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
5244                .setCaller(caller)
5245                .setCallingPackage(callingPackage)
5246                .setResolvedType(resolvedType)
5247                .setResultTo(resultTo)
5248                .setResultWho(resultWho)
5249                .setRequestCode(requestCode)
5250                .setStartFlags(startFlags)
5251                .setGlobalConfiguration(config)
5252                .setActivityOptions(bOptions)
5253                .setMayWait(userId)
5254                .execute();
5255    }
5256
5257    @Override
5258    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
5259            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
5260            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
5261            throws TransactionTooLargeException {
5262        enforceNotIsolatedCaller("startActivityIntentSender");
5263        // Refuse possible leaked file descriptors
5264        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
5265            throw new IllegalArgumentException("File descriptors passed in Intent");
5266        }
5267
5268        if (!(target instanceof PendingIntentRecord)) {
5269            throw new IllegalArgumentException("Bad PendingIntent object");
5270        }
5271
5272        PendingIntentRecord pir = (PendingIntentRecord)target;
5273
5274        synchronized (this) {
5275            // If this is coming from the currently resumed activity, it is
5276            // effectively saying that app switches are allowed at this point.
5277            final ActivityStack stack = getFocusedStack();
5278            if (stack.mResumedActivity != null &&
5279                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
5280                mAppSwitchesAllowedTime = 0;
5281            }
5282        }
5283        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
5284                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
5285        return ret;
5286    }
5287
5288    @Override
5289    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
5290            Intent intent, String resolvedType, IVoiceInteractionSession session,
5291            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
5292            Bundle bOptions, int userId) {
5293        enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
5294        if (session == null || interactor == null) {
5295            throw new NullPointerException("null session or interactor");
5296        }
5297        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5298                ALLOW_FULL_ONLY, "startVoiceActivity", null);
5299        // TODO: Switch to user app stacks here.
5300        return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
5301                .setCallingUid(callingUid)
5302                .setCallingPackage(callingPackage)
5303                .setResolvedType(resolvedType)
5304                .setVoiceSession(session)
5305                .setVoiceInteractor(interactor)
5306                .setStartFlags(startFlags)
5307                .setProfilerInfo(profilerInfo)
5308                .setActivityOptions(bOptions)
5309                .setMayWait(userId)
5310                .execute();
5311    }
5312
5313    @Override
5314    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
5315            Intent intent, String resolvedType, Bundle bOptions, int userId) {
5316        enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
5317        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5318                ALLOW_FULL_ONLY, "startAssistantActivity", null);
5319
5320        return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
5321                .setCallingUid(callingUid)
5322                .setCallingPackage(callingPackage)
5323                .setResolvedType(resolvedType)
5324                .setActivityOptions(bOptions)
5325                .setMayWait(userId)
5326                .execute();
5327    }
5328
5329    @Override
5330    public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
5331                IRecentsAnimationRunner recentsAnimationRunner) {
5332        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
5333        final int callingPid = Binder.getCallingPid();
5334        final long origId = Binder.clearCallingIdentity();
5335        try {
5336            synchronized (this) {
5337                final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
5338                final int recentsUid = mRecentTasks.getRecentsComponentUid();
5339
5340                // Start a new recents animation
5341                final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
5342                        mActivityStartController, mWindowManager, mUserController, callingPid);
5343                anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
5344                        recentsUid, assistDataReceiver);
5345            }
5346        } finally {
5347            Binder.restoreCallingIdentity(origId);
5348        }
5349    }
5350
5351    @Override
5352    public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
5353        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
5354        final long callingUid = Binder.getCallingUid();
5355        final long origId = Binder.clearCallingIdentity();
5356        try {
5357            synchronized (this) {
5358                // Cancel the recents animation synchronously (do not hold the WM lock)
5359                mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
5360                        ? REORDER_MOVE_TO_ORIGINAL_POSITION
5361                        : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
5362            }
5363        } finally {
5364            Binder.restoreCallingIdentity(origId);
5365        }
5366    }
5367
5368    @Override
5369    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
5370            throws RemoteException {
5371        Slog.i(TAG, "Activity tried to startVoiceInteraction");
5372        synchronized (this) {
5373            ActivityRecord activity = getFocusedStack().getTopActivity();
5374            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
5375                throw new SecurityException("Only focused activity can call startVoiceInteraction");
5376            }
5377            if (mRunningVoice != null || activity.getTask().voiceSession != null
5378                    || activity.voiceSession != null) {
5379                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
5380                return;
5381            }
5382            if (activity.pendingVoiceInteractionStart) {
5383                Slog.w(TAG, "Pending start of voice interaction already.");
5384                return;
5385            }
5386            activity.pendingVoiceInteractionStart = true;
5387        }
5388        LocalServices.getService(VoiceInteractionManagerInternal.class)
5389                .startLocalVoiceInteraction(callingActivity, options);
5390    }
5391
5392    @Override
5393    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
5394        LocalServices.getService(VoiceInteractionManagerInternal.class)
5395                .stopLocalVoiceInteraction(callingActivity);
5396    }
5397
5398    @Override
5399    public boolean supportsLocalVoiceInteraction() throws RemoteException {
5400        return LocalServices.getService(VoiceInteractionManagerInternal.class)
5401                .supportsLocalVoiceInteraction();
5402    }
5403
5404    @GuardedBy("this")
5405    void onLocalVoiceInteractionStartedLocked(IBinder activity,
5406            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5407        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
5408        if (activityToCallback == null) return;
5409        activityToCallback.setVoiceSessionLocked(voiceSession);
5410
5411        // Inform the activity
5412        try {
5413            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
5414                    voiceInteractor);
5415            long token = Binder.clearCallingIdentity();
5416            try {
5417                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
5418            } finally {
5419                Binder.restoreCallingIdentity(token);
5420            }
5421            // TODO: VI Should we cache the activity so that it's easier to find later
5422            // rather than scan through all the stacks and activities?
5423        } catch (RemoteException re) {
5424            activityToCallback.clearVoiceSessionLocked();
5425            // TODO: VI Should this terminate the voice session?
5426        }
5427    }
5428
5429    @Override
5430    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
5431        synchronized (this) {
5432            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
5433                if (keepAwake) {
5434                    mVoiceWakeLock.acquire();
5435                } else {
5436                    mVoiceWakeLock.release();
5437                }
5438            }
5439        }
5440    }
5441
5442    @Override
5443    public boolean startNextMatchingActivity(IBinder callingActivity,
5444            Intent intent, Bundle bOptions) {
5445        // Refuse possible leaked file descriptors
5446        if (intent != null && intent.hasFileDescriptors() == true) {
5447            throw new IllegalArgumentException("File descriptors passed in Intent");
5448        }
5449        SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
5450
5451        synchronized (this) {
5452            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
5453            if (r == null) {
5454                SafeActivityOptions.abort(options);
5455                return false;
5456            }
5457            if (r.app == null || r.app.thread == null) {
5458                // The caller is not running...  d'oh!
5459                SafeActivityOptions.abort(options);
5460                return false;
5461            }
5462            intent = new Intent(intent);
5463            // The caller is not allowed to change the data.
5464            intent.setDataAndType(r.intent.getData(), r.intent.getType());
5465            // And we are resetting to find the next component...
5466            intent.setComponent(null);
5467
5468            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5469
5470            ActivityInfo aInfo = null;
5471            try {
5472                List<ResolveInfo> resolves =
5473                    AppGlobals.getPackageManager().queryIntentActivities(
5474                            intent, r.resolvedType,
5475                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
5476                            UserHandle.getCallingUserId()).getList();
5477
5478                // Look for the original activity in the list...
5479                final int N = resolves != null ? resolves.size() : 0;
5480                for (int i=0; i<N; i++) {
5481                    ResolveInfo rInfo = resolves.get(i);
5482                    if (rInfo.activityInfo.packageName.equals(r.packageName)
5483                            && rInfo.activityInfo.name.equals(r.info.name)) {
5484                        // We found the current one...  the next matching is
5485                        // after it.
5486                        i++;
5487                        if (i<N) {
5488                            aInfo = resolves.get(i).activityInfo;
5489                        }
5490                        if (debug) {
5491                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
5492                                    + "/" + r.info.name);
5493                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
5494                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
5495                        }
5496                        break;
5497                    }
5498                }
5499            } catch (RemoteException e) {
5500            }
5501
5502            if (aInfo == null) {
5503                // Nobody who is next!
5504                SafeActivityOptions.abort(options);
5505                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
5506                return false;
5507            }
5508
5509            intent.setComponent(new ComponentName(
5510                    aInfo.applicationInfo.packageName, aInfo.name));
5511            intent.setFlags(intent.getFlags()&~(
5512                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
5513                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
5514                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
5515                    FLAG_ACTIVITY_NEW_TASK));
5516
5517            // Okay now we need to start the new activity, replacing the
5518            // currently running activity.  This is a little tricky because
5519            // we want to start the new one as if the current one is finished,
5520            // but not finish the current one first so that there is no flicker.
5521            // And thus...
5522            final boolean wasFinishing = r.finishing;
5523            r.finishing = true;
5524
5525            // Propagate reply information over to the new activity.
5526            final ActivityRecord resultTo = r.resultTo;
5527            final String resultWho = r.resultWho;
5528            final int requestCode = r.requestCode;
5529            r.resultTo = null;
5530            if (resultTo != null) {
5531                resultTo.removeResultsLocked(r, resultWho, requestCode);
5532            }
5533
5534            final long origId = Binder.clearCallingIdentity();
5535            // TODO(b/64750076): Check if calling pid should really be -1.
5536            final int res = mActivityStartController
5537                    .obtainStarter(intent, "startNextMatchingActivity")
5538                    .setCaller(r.app.thread)
5539                    .setResolvedType(r.resolvedType)
5540                    .setActivityInfo(aInfo)
5541                    .setResultTo(resultTo != null ? resultTo.appToken : null)
5542                    .setResultWho(resultWho)
5543                    .setRequestCode(requestCode)
5544                    .setCallingPid(-1)
5545                    .setCallingUid(r.launchedFromUid)
5546                    .setCallingPackage(r.launchedFromPackage)
5547                    .setRealCallingPid(-1)
5548                    .setRealCallingUid(r.launchedFromUid)
5549                    .setActivityOptions(options)
5550                    .execute();
5551            Binder.restoreCallingIdentity(origId);
5552
5553            r.finishing = wasFinishing;
5554            if (res != ActivityManager.START_SUCCESS) {
5555                return false;
5556            }
5557            return true;
5558        }
5559    }
5560
5561    @Override
5562    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
5563        enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
5564                "startActivityFromRecents()");
5565
5566        final int callingPid = Binder.getCallingPid();
5567        final int callingUid = Binder.getCallingUid();
5568        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
5569        final long origId = Binder.clearCallingIdentity();
5570        try {
5571            synchronized (this) {
5572                return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
5573                        safeOptions);
5574            }
5575        } finally {
5576            Binder.restoreCallingIdentity(origId);
5577        }
5578    }
5579
5580    @Override
5581    public final int startActivities(IApplicationThread caller, String callingPackage,
5582            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
5583            int userId) {
5584        final String reason = "startActivities";
5585        enforceNotIsolatedCaller(reason);
5586        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5587                userId, false, ALLOW_FULL_ONLY, reason, null);
5588        // TODO: Switch to user app stacks here.
5589        int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
5590                intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
5591                reason);
5592        return ret;
5593    }
5594
5595    @Override
5596    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
5597        synchronized (this) {
5598            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5599            if (r == null) {
5600                return;
5601            }
5602            r.reportFullyDrawnLocked(restoredFromBundle);
5603        }
5604    }
5605
5606    @Override
5607    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
5608        synchronized (this) {
5609            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5610            if (r == null) {
5611                return;
5612            }
5613            final long origId = Binder.clearCallingIdentity();
5614            try {
5615                r.setRequestedOrientation(requestedOrientation);
5616            } finally {
5617                Binder.restoreCallingIdentity(origId);
5618            }
5619        }
5620    }
5621
5622    @Override
5623    public int getRequestedOrientation(IBinder token) {
5624        synchronized (this) {
5625            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5626            if (r == null) {
5627                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5628            }
5629            return r.getRequestedOrientation();
5630        }
5631    }
5632
5633    /**
5634     * This is the internal entry point for handling Activity.finish().
5635     *
5636     * @param token The Binder token referencing the Activity we want to finish.
5637     * @param resultCode Result code, if any, from this Activity.
5638     * @param resultData Result data (Intent), if any, from this Activity.
5639     * @param finishTask Whether to finish the task associated with this Activity.
5640     *
5641     * @return Returns true if the activity successfully finished, or false if it is still running.
5642     */
5643    @Override
5644    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5645            int finishTask) {
5646        // Refuse possible leaked file descriptors
5647        if (resultData != null && resultData.hasFileDescriptors() == true) {
5648            throw new IllegalArgumentException("File descriptors passed in Intent");
5649        }
5650
5651        synchronized(this) {
5652            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5653            if (r == null) {
5654                return true;
5655            }
5656            // Keep track of the root activity of the task before we finish it
5657            TaskRecord tr = r.getTask();
5658            ActivityRecord rootR = tr.getRootActivity();
5659            if (rootR == null) {
5660                Slog.w(TAG, "Finishing task with all activities already finished");
5661            }
5662            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5663            // finish.
5664            if (mLockTaskController.activityBlockedFromFinish(r)) {
5665                return false;
5666            }
5667
5668            if (mController != null) {
5669                // Find the first activity that is not finishing.
5670                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5671                if (next != null) {
5672                    // ask watcher if this is allowed
5673                    boolean resumeOK = true;
5674                    try {
5675                        resumeOK = mController.activityResuming(next.packageName);
5676                    } catch (RemoteException e) {
5677                        mController = null;
5678                        Watchdog.getInstance().setActivityController(null);
5679                    }
5680
5681                    if (!resumeOK) {
5682                        Slog.i(TAG, "Not finishing activity because controller resumed");
5683                        return false;
5684                    }
5685                }
5686            }
5687            final long origId = Binder.clearCallingIdentity();
5688            try {
5689                boolean res;
5690                final boolean finishWithRootActivity =
5691                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5692                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5693                        || (finishWithRootActivity && r == rootR)) {
5694                    // If requested, remove the task that is associated to this activity only if it
5695                    // was the root activity in the task. The result code and data is ignored
5696                    // because we don't support returning them across task boundaries. Also, to
5697                    // keep backwards compatibility we remove the task from recents when finishing
5698                    // task with root activity.
5699                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5700                            finishWithRootActivity, "finish-activity");
5701                    if (!res) {
5702                        Slog.i(TAG, "Removing task failed to finish activity");
5703                    }
5704                } else {
5705                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5706                            resultData, "app-request", true);
5707                    if (!res) {
5708                        Slog.i(TAG, "Failed to finish by app-request");
5709                    }
5710                }
5711                return res;
5712            } finally {
5713                Binder.restoreCallingIdentity(origId);
5714            }
5715        }
5716    }
5717
5718    @Override
5719    public final void finishHeavyWeightApp() {
5720        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5721                != PackageManager.PERMISSION_GRANTED) {
5722            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5723                    + Binder.getCallingPid()
5724                    + ", uid=" + Binder.getCallingUid()
5725                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5726            Slog.w(TAG, msg);
5727            throw new SecurityException(msg);
5728        }
5729
5730        synchronized(this) {
5731            final ProcessRecord proc = mHeavyWeightProcess;
5732            if (proc == null) {
5733                return;
5734            }
5735
5736            ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
5737            for (int i = 0; i < activities.size(); i++) {
5738                ActivityRecord r = activities.get(i);
5739                if (!r.finishing && r.isInStackLocked()) {
5740                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5741                            null, "finish-heavy", true);
5742                }
5743            }
5744
5745            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5746                    proc.userId, 0));
5747            mHeavyWeightProcess = null;
5748        }
5749    }
5750
5751    @Override
5752    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5753            String message) {
5754        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5755                != PackageManager.PERMISSION_GRANTED) {
5756            String msg = "Permission Denial: crashApplication() from pid="
5757                    + Binder.getCallingPid()
5758                    + ", uid=" + Binder.getCallingUid()
5759                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5760            Slog.w(TAG, msg);
5761            throw new SecurityException(msg);
5762        }
5763
5764        synchronized(this) {
5765            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5766        }
5767    }
5768
5769    @Override
5770    public final void finishSubActivity(IBinder token, String resultWho,
5771            int requestCode) {
5772        synchronized(this) {
5773            final long origId = Binder.clearCallingIdentity();
5774            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5775            if (r != null) {
5776                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5777            }
5778            Binder.restoreCallingIdentity(origId);
5779        }
5780    }
5781
5782    @Override
5783    public boolean finishActivityAffinity(IBinder token) {
5784        synchronized(this) {
5785            final long origId = Binder.clearCallingIdentity();
5786            try {
5787                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5788                if (r == null) {
5789                    return false;
5790                }
5791
5792                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5793                // can finish.
5794                final TaskRecord task = r.getTask();
5795                if (mLockTaskController.activityBlockedFromFinish(r)) {
5796                    return false;
5797                }
5798                return task.getStack().finishActivityAffinityLocked(r);
5799            } finally {
5800                Binder.restoreCallingIdentity(origId);
5801            }
5802        }
5803    }
5804
5805    @Override
5806    public void finishVoiceTask(IVoiceInteractionSession session) {
5807        synchronized (this) {
5808            final long origId = Binder.clearCallingIdentity();
5809            try {
5810                // TODO: VI Consider treating local voice interactions and voice tasks
5811                // differently here
5812                mStackSupervisor.finishVoiceTask(session);
5813            } finally {
5814                Binder.restoreCallingIdentity(origId);
5815            }
5816        }
5817
5818    }
5819
5820    @Override
5821    public boolean releaseActivityInstance(IBinder token) {
5822        synchronized(this) {
5823            final long origId = Binder.clearCallingIdentity();
5824            try {
5825                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5826                if (r == null) {
5827                    return false;
5828                }
5829                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5830            } finally {
5831                Binder.restoreCallingIdentity(origId);
5832            }
5833        }
5834    }
5835
5836    @Override
5837    public void releaseSomeActivities(IApplicationThread appInt) {
5838        synchronized(this) {
5839            final long origId = Binder.clearCallingIdentity();
5840            try {
5841                ProcessRecord app = getRecordForAppLocked(appInt);
5842                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5843            } finally {
5844                Binder.restoreCallingIdentity(origId);
5845            }
5846        }
5847    }
5848
5849    @Override
5850    public boolean willActivityBeVisible(IBinder token) {
5851        synchronized(this) {
5852            ActivityStack stack = ActivityRecord.getStackLocked(token);
5853            if (stack != null) {
5854                return stack.willActivityBeVisibleLocked(token);
5855            }
5856            return false;
5857        }
5858    }
5859
5860    @Override
5861    public void overridePendingTransition(IBinder token, String packageName,
5862            int enterAnim, int exitAnim) {
5863        synchronized(this) {
5864            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5865            if (self == null) {
5866                return;
5867            }
5868
5869            final long origId = Binder.clearCallingIdentity();
5870
5871            if (self.isState(ActivityState.RESUMED, ActivityState.PAUSING)) {
5872                mWindowManager.overridePendingAppTransition(packageName,
5873                        enterAnim, exitAnim, null);
5874            }
5875
5876            Binder.restoreCallingIdentity(origId);
5877        }
5878    }
5879
5880    /**
5881     * Main function for removing an existing process from the activity manager
5882     * as a result of that process going away.  Clears out all connections
5883     * to the process.
5884     */
5885    @GuardedBy("this")
5886    private final void handleAppDiedLocked(ProcessRecord app,
5887            boolean restarting, boolean allowRestart) {
5888        int pid = app.pid;
5889        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5890                false /*replacingPid*/);
5891        if (!kept && !restarting) {
5892            removeLruProcessLocked(app);
5893            if (pid > 0) {
5894                ProcessList.remove(pid);
5895            }
5896        }
5897
5898        if (mProfileProc == app) {
5899            clearProfilerLocked();
5900        }
5901
5902        // Remove this application's activities from active lists.
5903        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5904
5905        app.clearRecentTasks();
5906
5907        app.activities.clear();
5908
5909        if (app.instr != null) {
5910            Slog.w(TAG, "Crash of app " + app.processName
5911                  + " running instrumentation " + app.instr.mClass);
5912            Bundle info = new Bundle();
5913            info.putString("shortMsg", "Process crashed.");
5914            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5915        }
5916
5917        mWindowManager.deferSurfaceLayout();
5918        try {
5919            if (!restarting && hasVisibleActivities
5920                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5921                // If there was nothing to resume, and we are not already restarting this process, but
5922                // there is a visible activity that is hosted by the process...  then make sure all
5923                // visible activities are running, taking care of restarting this process.
5924                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5925            }
5926        } finally {
5927            mWindowManager.continueSurfaceLayout();
5928        }
5929    }
5930
5931    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5932        final IBinder threadBinder = thread.asBinder();
5933        // Find the application record.
5934        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5935            final ProcessRecord rec = mLruProcesses.get(i);
5936            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5937                return i;
5938            }
5939        }
5940        return -1;
5941    }
5942
5943    ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
5944        if (thread == null) {
5945            return null;
5946        }
5947
5948        int appIndex = getLRURecordIndexForAppLocked(thread);
5949        if (appIndex >= 0) {
5950            return mLruProcesses.get(appIndex);
5951        }
5952
5953        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5954        // double-check that.
5955        final IBinder threadBinder = thread.asBinder();
5956        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5957        for (int i = pmap.size()-1; i >= 0; i--) {
5958            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5959            for (int j = procs.size()-1; j >= 0; j--) {
5960                final ProcessRecord proc = procs.valueAt(j);
5961                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5962                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5963                            + proc);
5964                    return proc;
5965                }
5966            }
5967        }
5968
5969        return null;
5970    }
5971
5972    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5973        // If there are no longer any background processes running,
5974        // and the app that died was not running instrumentation,
5975        // then tell everyone we are now low on memory.
5976        boolean haveBg = false;
5977        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5978            ProcessRecord rec = mLruProcesses.get(i);
5979            if (rec.thread != null
5980                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5981                haveBg = true;
5982                break;
5983            }
5984        }
5985
5986        if (!haveBg) {
5987            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5988            if (doReport) {
5989                long now = SystemClock.uptimeMillis();
5990                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5991                    doReport = false;
5992                } else {
5993                    mLastMemUsageReportTime = now;
5994                }
5995            }
5996            final ArrayList<ProcessMemInfo> memInfos
5997                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5998            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5999            long now = SystemClock.uptimeMillis();
6000            for (int i=mLruProcesses.size()-1; i>=0; i--) {
6001                ProcessRecord rec = mLruProcesses.get(i);
6002                if (rec == dyingProc || rec.thread == null) {
6003                    continue;
6004                }
6005                if (doReport) {
6006                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
6007                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
6008                }
6009                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
6010                    // The low memory report is overriding any current
6011                    // state for a GC request.  Make sure to do
6012                    // heavy/important/visible/foreground processes first.
6013                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
6014                        rec.lastRequestedGc = 0;
6015                    } else {
6016                        rec.lastRequestedGc = rec.lastLowMemory;
6017                    }
6018                    rec.reportLowMemory = true;
6019                    rec.lastLowMemory = now;
6020                    mProcessesToGc.remove(rec);
6021                    addProcessToGcListLocked(rec);
6022                }
6023            }
6024            if (doReport) {
6025                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
6026                mHandler.sendMessage(msg);
6027            }
6028            scheduleAppGcsLocked();
6029        }
6030    }
6031
6032    @GuardedBy("this")
6033    final void appDiedLocked(ProcessRecord app) {
6034       appDiedLocked(app, app.pid, app.thread, false);
6035    }
6036
6037    @GuardedBy("this")
6038    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
6039            boolean fromBinderDied) {
6040        // First check if this ProcessRecord is actually active for the pid.
6041        synchronized (mPidsSelfLocked) {
6042            ProcessRecord curProc = mPidsSelfLocked.get(pid);
6043            if (curProc != app) {
6044                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
6045                return;
6046            }
6047        }
6048
6049        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6050        synchronized (stats) {
6051            stats.noteProcessDiedLocked(app.info.uid, pid);
6052        }
6053
6054        if (!app.killed) {
6055            if (!fromBinderDied) {
6056                killProcessQuiet(pid);
6057            }
6058            killProcessGroup(app.uid, pid);
6059            app.killed = true;
6060        }
6061
6062        // Clean up already done if the process has been re-started.
6063        if (app.pid == pid && app.thread != null &&
6064                app.thread.asBinder() == thread.asBinder()) {
6065            boolean doLowMem = app.instr == null;
6066            boolean doOomAdj = doLowMem;
6067            if (!app.killedByAm) {
6068                reportUidInfoMessageLocked(TAG,
6069                        "Process " + app.processName + " (pid " + pid + ") has died: "
6070                                + ProcessList.makeOomAdjString(app.setAdj)
6071                                + ProcessList.makeProcStateString(app.setProcState), app.info.uid);
6072                mAllowLowerMemLevel = true;
6073            } else {
6074                // Note that we always want to do oom adj to update our state with the
6075                // new number of procs.
6076                mAllowLowerMemLevel = false;
6077                doLowMem = false;
6078            }
6079            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
6080                    app.setAdj, app.setProcState);
6081            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
6082                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
6083            handleAppDiedLocked(app, false, true);
6084
6085            if (doOomAdj) {
6086                updateOomAdjLocked();
6087            }
6088            if (doLowMem) {
6089                doLowMemReportIfNeededLocked(app);
6090            }
6091        } else if (app.pid != pid) {
6092            // A new process has already been started.
6093            reportUidInfoMessageLocked(TAG,
6094                    "Process " + app.processName + " (pid " + pid
6095                            + ") has died and restarted (pid " + app.pid + ").", app.info.uid);
6096            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
6097        } else if (DEBUG_PROCESSES) {
6098            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
6099                    + thread.asBinder());
6100        }
6101
6102        // On the device which doesn't have Cgroup, log LmkStateChanged which is used as a signal
6103        // for pulling memory stats of other running processes when this process died.
6104        if (!hasMemcg()) {
6105            StatsLog.write(StatsLog.APP_DIED, SystemClock.elapsedRealtime());
6106        }
6107    }
6108
6109    /**
6110     * If a stack trace dump file is configured, dump process stack traces.
6111     * @param clearTraces causes the dump file to be erased prior to the new
6112     *    traces being written, if true; when false, the new traces will be
6113     *    appended to any existing file content.
6114     * @param firstPids of dalvik VM processes to dump stack traces for first
6115     * @param lastPids of dalvik VM processes to dump stack traces for last
6116     * @param nativePids optional list of native pids to dump stack crawls
6117     */
6118    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
6119            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
6120            ArrayList<Integer> nativePids) {
6121        ArrayList<Integer> extraPids = null;
6122
6123        // Measure CPU usage as soon as we're called in order to get a realistic sampling
6124        // of the top users at the time of the request.
6125        if (processCpuTracker != null) {
6126            processCpuTracker.init();
6127            try {
6128                Thread.sleep(200);
6129            } catch (InterruptedException ignored) {
6130            }
6131
6132            processCpuTracker.update();
6133
6134            // We'll take the stack crawls of just the top apps using CPU.
6135            final int N = processCpuTracker.countWorkingStats();
6136            extraPids = new ArrayList<>();
6137            for (int i = 0; i < N && extraPids.size() < 5; i++) {
6138                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
6139                if (lastPids.indexOfKey(stats.pid) >= 0) {
6140                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
6141
6142                    extraPids.add(stats.pid);
6143                } else if (DEBUG_ANR) {
6144                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
6145                            + stats.pid);
6146                }
6147            }
6148        }
6149
6150        boolean useTombstonedForJavaTraces = false;
6151        File tracesFile;
6152
6153        final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
6154        if (tracesDirProp.isEmpty()) {
6155            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
6156            // dumping scheme. All traces are written to a global trace file (usually
6157            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
6158            // the file if requested.
6159            //
6160            // This mode of operation will be removed in the near future.
6161
6162
6163            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6164            if (globalTracesPath.isEmpty()) {
6165                Slog.w(TAG, "dumpStackTraces: no trace path configured");
6166                return null;
6167            }
6168
6169            tracesFile = new File(globalTracesPath);
6170            try {
6171                if (clearTraces && tracesFile.exists()) {
6172                    tracesFile.delete();
6173                }
6174
6175                tracesFile.createNewFile();
6176                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
6177            } catch (IOException e) {
6178                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
6179                return null;
6180            }
6181        } else {
6182            File tracesDir = new File(tracesDirProp);
6183            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
6184            // Each set of ANR traces is written to a separate file and dumpstate will process
6185            // all such files and add them to a captured bug report if they're recent enough.
6186            maybePruneOldTraces(tracesDir);
6187
6188            // NOTE: We should consider creating the file in native code atomically once we've
6189            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
6190            // can be removed.
6191            tracesFile = createAnrDumpFile(tracesDir);
6192            if (tracesFile == null) {
6193                return null;
6194            }
6195
6196            useTombstonedForJavaTraces = true;
6197        }
6198
6199        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
6200                useTombstonedForJavaTraces);
6201        return tracesFile;
6202    }
6203
6204    @GuardedBy("ActivityManagerService.class")
6205    private static SimpleDateFormat sAnrFileDateFormat;
6206
6207    private static synchronized File createAnrDumpFile(File tracesDir) {
6208        if (sAnrFileDateFormat == null) {
6209            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
6210        }
6211
6212        final String formattedDate = sAnrFileDateFormat.format(new Date());
6213        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
6214
6215        try {
6216            if (anrFile.createNewFile()) {
6217                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
6218                return anrFile;
6219            } else {
6220                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
6221            }
6222        } catch (IOException ioe) {
6223            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
6224        }
6225
6226        return null;
6227    }
6228
6229    /**
6230     * Prune all trace files that are more than a day old.
6231     *
6232     * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
6233     * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
6234     * since it's the system_server that creates trace files for most ANRs.
6235     */
6236    private static void maybePruneOldTraces(File tracesDir) {
6237        final long now = System.currentTimeMillis();
6238        final File[] traceFiles = tracesDir.listFiles();
6239
6240        if (traceFiles != null) {
6241            for (File file : traceFiles) {
6242                if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
6243                    if (!file.delete()) {
6244                        Slog.w(TAG, "Unable to prune stale trace file: " + file);
6245                    }
6246                }
6247            }
6248        }
6249    }
6250
6251    /**
6252     * Legacy code, do not use. Existing users will be deleted.
6253     *
6254     * @deprecated
6255     */
6256    @Deprecated
6257    public static class DumpStackFileObserver extends FileObserver {
6258        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
6259        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
6260
6261        private final String mTracesPath;
6262        private boolean mClosed;
6263
6264        public DumpStackFileObserver(String tracesPath) {
6265            super(tracesPath, FileObserver.CLOSE_WRITE);
6266            mTracesPath = tracesPath;
6267        }
6268
6269        @Override
6270        public synchronized void onEvent(int event, String path) {
6271            mClosed = true;
6272            notify();
6273        }
6274
6275        public long dumpWithTimeout(int pid, long timeout) {
6276            sendSignal(pid, SIGNAL_QUIT);
6277            final long start = SystemClock.elapsedRealtime();
6278
6279            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
6280            synchronized (this) {
6281                try {
6282                    wait(waitTime); // Wait for traces file to be closed.
6283                } catch (InterruptedException e) {
6284                    Slog.wtf(TAG, e);
6285                }
6286            }
6287
6288            // This avoids a corner case of passing a negative time to the native
6289            // trace in case we've already hit the overall timeout.
6290            final long timeWaited = SystemClock.elapsedRealtime() - start;
6291            if (timeWaited >= timeout) {
6292                return timeWaited;
6293            }
6294
6295            if (!mClosed) {
6296                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
6297                       ". Attempting native stack collection.");
6298
6299                final long nativeDumpTimeoutMs = Math.min(
6300                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
6301
6302                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
6303                        (int) (nativeDumpTimeoutMs / 1000));
6304            }
6305
6306            final long end = SystemClock.elapsedRealtime();
6307            mClosed = false;
6308
6309            return (end - start);
6310        }
6311    }
6312
6313    /**
6314     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
6315     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
6316     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
6317     * attempting to obtain native traces in the case of a failure. Returns the total time spent
6318     * capturing traces.
6319     */
6320    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
6321        final long timeStart = SystemClock.elapsedRealtime();
6322        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
6323            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
6324                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
6325        }
6326
6327        return SystemClock.elapsedRealtime() - timeStart;
6328    }
6329
6330    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
6331            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
6332            boolean useTombstonedForJavaTraces) {
6333
6334        // We don't need any sort of inotify based monitoring when we're dumping traces via
6335        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
6336        // control of all writes to the file in question.
6337        final DumpStackFileObserver observer;
6338        if (useTombstonedForJavaTraces) {
6339            observer = null;
6340        } else {
6341            // Use a FileObserver to detect when traces finish writing.
6342            // The order of traces is considered important to maintain for legibility.
6343            observer = new DumpStackFileObserver(tracesFile);
6344        }
6345
6346        // We must complete all stack dumps within 20 seconds.
6347        long remainingTime = 20 * 1000;
6348        try {
6349            if (observer != null) {
6350                observer.startWatching();
6351            }
6352
6353            // First collect all of the stacks of the most important pids.
6354            if (firstPids != null) {
6355                int num = firstPids.size();
6356                for (int i = 0; i < num; i++) {
6357                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
6358                            + firstPids.get(i));
6359                    final long timeTaken;
6360                    if (useTombstonedForJavaTraces) {
6361                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
6362                    } else {
6363                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
6364                    }
6365
6366                    remainingTime -= timeTaken;
6367                    if (remainingTime <= 0) {
6368                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
6369                            "); deadline exceeded.");
6370                        return;
6371                    }
6372
6373                    if (DEBUG_ANR) {
6374                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
6375                    }
6376                }
6377            }
6378
6379            // Next collect the stacks of the native pids
6380            if (nativePids != null) {
6381                for (int pid : nativePids) {
6382                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
6383                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
6384
6385                    final long start = SystemClock.elapsedRealtime();
6386                    Debug.dumpNativeBacktraceToFileTimeout(
6387                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
6388                    final long timeTaken = SystemClock.elapsedRealtime() - start;
6389
6390                    remainingTime -= timeTaken;
6391                    if (remainingTime <= 0) {
6392                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
6393                            "); deadline exceeded.");
6394                        return;
6395                    }
6396
6397                    if (DEBUG_ANR) {
6398                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
6399                    }
6400                }
6401            }
6402
6403            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
6404            if (extraPids != null) {
6405                for (int pid : extraPids) {
6406                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
6407
6408                    final long timeTaken;
6409                    if (useTombstonedForJavaTraces) {
6410                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
6411                    } else {
6412                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
6413                    }
6414
6415                    remainingTime -= timeTaken;
6416                    if (remainingTime <= 0) {
6417                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
6418                                "); deadline exceeded.");
6419                        return;
6420                    }
6421
6422                    if (DEBUG_ANR) {
6423                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
6424                    }
6425                }
6426            }
6427        } finally {
6428            if (observer != null) {
6429                observer.stopWatching();
6430            }
6431        }
6432    }
6433
6434    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
6435        if (true || Build.IS_USER) {
6436            return;
6437        }
6438        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6439        if (tracesPath == null || tracesPath.length() == 0) {
6440            return;
6441        }
6442
6443        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
6444        StrictMode.allowThreadDiskWrites();
6445        try {
6446            final File tracesFile = new File(tracesPath);
6447            final File tracesDir = tracesFile.getParentFile();
6448            final File tracesTmp = new File(tracesDir, "__tmp__");
6449            try {
6450                if (tracesFile.exists()) {
6451                    tracesTmp.delete();
6452                    tracesFile.renameTo(tracesTmp);
6453                }
6454                StringBuilder sb = new StringBuilder();
6455                Time tobj = new Time();
6456                tobj.set(System.currentTimeMillis());
6457                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
6458                sb.append(": ");
6459                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
6460                sb.append(" since ");
6461                sb.append(msg);
6462                FileOutputStream fos = new FileOutputStream(tracesFile);
6463                fos.write(sb.toString().getBytes());
6464                if (app == null) {
6465                    fos.write("\n*** No application process!".getBytes());
6466                }
6467                fos.close();
6468                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
6469            } catch (IOException e) {
6470                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
6471                return;
6472            }
6473
6474            if (app != null && app.pid > 0) {
6475                ArrayList<Integer> firstPids = new ArrayList<Integer>();
6476                firstPids.add(app.pid);
6477                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
6478            }
6479
6480            File lastTracesFile = null;
6481            File curTracesFile = null;
6482            for (int i=9; i>=0; i--) {
6483                String name = String.format(Locale.US, "slow%02d.txt", i);
6484                curTracesFile = new File(tracesDir, name);
6485                if (curTracesFile.exists()) {
6486                    if (lastTracesFile != null) {
6487                        curTracesFile.renameTo(lastTracesFile);
6488                    } else {
6489                        curTracesFile.delete();
6490                    }
6491                }
6492                lastTracesFile = curTracesFile;
6493            }
6494            tracesFile.renameTo(curTracesFile);
6495            if (tracesTmp.exists()) {
6496                tracesTmp.renameTo(tracesFile);
6497            }
6498        } finally {
6499            StrictMode.setThreadPolicy(oldPolicy);
6500        }
6501    }
6502
6503    @GuardedBy("this")
6504    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
6505        if (!mLaunchWarningShown) {
6506            mLaunchWarningShown = true;
6507            mUiHandler.post(new Runnable() {
6508                @Override
6509                public void run() {
6510                    synchronized (ActivityManagerService.this) {
6511                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
6512                        d.show();
6513                        mUiHandler.postDelayed(new Runnable() {
6514                            @Override
6515                            public void run() {
6516                                synchronized (ActivityManagerService.this) {
6517                                    d.dismiss();
6518                                    mLaunchWarningShown = false;
6519                                }
6520                            }
6521                        }, 4000);
6522                    }
6523                }
6524            });
6525        }
6526    }
6527
6528    @Override
6529    public boolean clearApplicationUserData(final String packageName, boolean keepState,
6530            final IPackageDataObserver observer, int userId) {
6531        enforceNotIsolatedCaller("clearApplicationUserData");
6532        int uid = Binder.getCallingUid();
6533        int pid = Binder.getCallingPid();
6534        final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
6535                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
6536
6537        final ApplicationInfo appInfo;
6538        final boolean isInstantApp;
6539
6540        long callingId = Binder.clearCallingIdentity();
6541        try {
6542            IPackageManager pm = AppGlobals.getPackageManager();
6543            synchronized(this) {
6544                // Instant packages are not protected
6545                if (getPackageManagerInternalLocked().isPackageDataProtected(
6546                        resolvedUserId, packageName)) {
6547                    throw new SecurityException(
6548                            "Cannot clear data for a protected package: " + packageName);
6549                }
6550
6551                ApplicationInfo applicationInfo = null;
6552                try {
6553                    applicationInfo = pm.getApplicationInfo(packageName,
6554                            MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
6555                } catch (RemoteException e) {
6556                    /* ignore */
6557                }
6558                appInfo = applicationInfo;
6559
6560                final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
6561
6562                if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
6563                        pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
6564                    throw new SecurityException("PID " + pid + " does not have permission "
6565                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
6566                            + " of package " + packageName);
6567                }
6568
6569                final boolean hasInstantMetadata = getPackageManagerInternalLocked()
6570                        .hasInstantApplicationMetadata(packageName, resolvedUserId);
6571                final boolean isUninstalledAppWithoutInstantMetadata =
6572                        (appInfo == null && !hasInstantMetadata);
6573                isInstantApp = (appInfo != null && appInfo.isInstantApp())
6574                        || hasInstantMetadata;
6575                final boolean canAccessInstantApps = checkComponentPermission(
6576                        permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
6577                        == PackageManager.PERMISSION_GRANTED;
6578
6579                if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
6580                        && !canAccessInstantApps)) {
6581                    Slog.w(TAG, "Invalid packageName: " + packageName);
6582                    if (observer != null) {
6583                        try {
6584                            observer.onRemoveCompleted(packageName, false);
6585                        } catch (RemoteException e) {
6586                            Slog.i(TAG, "Observer no longer exists.");
6587                        }
6588                    }
6589                    return false;
6590                }
6591
6592                if (appInfo != null) {
6593                    forceStopPackageLocked(packageName, appInfo.uid, "clear data");
6594                    mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
6595                }
6596            }
6597
6598            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
6599                @Override
6600                public void onRemoveCompleted(String packageName, boolean succeeded)
6601                        throws RemoteException {
6602                    if (appInfo != null) {
6603                        synchronized (ActivityManagerService.this) {
6604                            finishForceStopPackageLocked(packageName, appInfo.uid);
6605                        }
6606                    }
6607                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
6608                            Uri.fromParts("package", packageName, null));
6609                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6610                    intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6611                    intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6612                    if (isInstantApp) {
6613                        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6614                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6615                                null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6616                                resolvedUserId);
6617                    } else {
6618                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6619                                null, null, null, null, false, false, resolvedUserId);
6620                    }
6621
6622                    if (observer != null) {
6623                        observer.onRemoveCompleted(packageName, succeeded);
6624                    }
6625                }
6626            };
6627
6628            try {
6629                // Clear application user data
6630                pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6631
6632                if (appInfo != null) {
6633                    // Restore already established notification state and permission grants,
6634                    // so it told us to keep those intact -- it's about to emplace app data
6635                    // that is appropriate for those bits of system state.
6636                    if (!keepState) {
6637                        synchronized (this) {
6638                            // Remove all permissions granted from/to this package
6639                            removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true,
6640                                    false);
6641                        }
6642
6643                        // Reset notification state
6644                        INotificationManager inm = NotificationManager.getService();
6645                        inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6646                    }
6647
6648                    // Clear its scheduled jobs
6649                    JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
6650                    js.cancelJobsForUid(appInfo.uid, "clear data");
6651
6652                    // Clear its pending alarms
6653                    AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
6654                    ami.removeAlarmsForUid(appInfo.uid);
6655                }
6656            } catch (RemoteException e) {
6657            }
6658        } finally {
6659            Binder.restoreCallingIdentity(callingId);
6660        }
6661        return true;
6662    }
6663
6664    @Override
6665    public void killBackgroundProcesses(final String packageName, int userId) {
6666        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6667                != PackageManager.PERMISSION_GRANTED &&
6668                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6669                        != PackageManager.PERMISSION_GRANTED) {
6670            String msg = "Permission Denial: killBackgroundProcesses() from pid="
6671                    + Binder.getCallingPid()
6672                    + ", uid=" + Binder.getCallingUid()
6673                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6674            Slog.w(TAG, msg);
6675            throw new SecurityException(msg);
6676        }
6677
6678        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6679                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6680        final int[] userIds = mUserController.expandUserId(userId);
6681
6682        long callingId = Binder.clearCallingIdentity();
6683        try {
6684            IPackageManager pm = AppGlobals.getPackageManager();
6685            for (int targetUserId : userIds) {
6686                int appId = -1;
6687                try {
6688                    appId = UserHandle.getAppId(
6689                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6690                                    targetUserId));
6691                } catch (RemoteException e) {
6692                }
6693                if (appId == -1) {
6694                    Slog.w(TAG, "Invalid packageName: " + packageName);
6695                    return;
6696                }
6697                synchronized (this) {
6698                    killPackageProcessesLocked(packageName, appId, targetUserId,
6699                            ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6700                }
6701            }
6702        } finally {
6703            Binder.restoreCallingIdentity(callingId);
6704        }
6705    }
6706
6707    @Override
6708    public void killAllBackgroundProcesses() {
6709        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6710                != PackageManager.PERMISSION_GRANTED) {
6711            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6712                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6713                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6714            Slog.w(TAG, msg);
6715            throw new SecurityException(msg);
6716        }
6717
6718        final long callingId = Binder.clearCallingIdentity();
6719        try {
6720            synchronized (this) {
6721                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6722                final int NP = mProcessNames.getMap().size();
6723                for (int ip = 0; ip < NP; ip++) {
6724                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6725                    final int NA = apps.size();
6726                    for (int ia = 0; ia < NA; ia++) {
6727                        final ProcessRecord app = apps.valueAt(ia);
6728                        if (app.persistent) {
6729                            // We don't kill persistent processes.
6730                            continue;
6731                        }
6732                        if (app.removed) {
6733                            procs.add(app);
6734                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6735                            app.removed = true;
6736                            procs.add(app);
6737                        }
6738                    }
6739                }
6740
6741                final int N = procs.size();
6742                for (int i = 0; i < N; i++) {
6743                    removeProcessLocked(procs.get(i), false, true, "kill all background");
6744                }
6745
6746                mAllowLowerMemLevel = true;
6747
6748                updateOomAdjLocked();
6749                doLowMemReportIfNeededLocked(null);
6750            }
6751        } finally {
6752            Binder.restoreCallingIdentity(callingId);
6753        }
6754    }
6755
6756    /**
6757     * Kills all background processes, except those matching any of the
6758     * specified properties.
6759     *
6760     * @param minTargetSdk the target SDK version at or above which to preserve
6761     *                     processes, or {@code -1} to ignore the target SDK
6762     * @param maxProcState the process state at or below which to preserve
6763     *                     processes, or {@code -1} to ignore the process state
6764     */
6765    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6766        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6767                != PackageManager.PERMISSION_GRANTED) {
6768            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6769                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6770                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6771            Slog.w(TAG, msg);
6772            throw new SecurityException(msg);
6773        }
6774
6775        final long callingId = Binder.clearCallingIdentity();
6776        try {
6777            synchronized (this) {
6778                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6779                final int NP = mProcessNames.getMap().size();
6780                for (int ip = 0; ip < NP; ip++) {
6781                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6782                    final int NA = apps.size();
6783                    for (int ia = 0; ia < NA; ia++) {
6784                        final ProcessRecord app = apps.valueAt(ia);
6785                        if (app.removed) {
6786                            procs.add(app);
6787                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6788                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6789                            app.removed = true;
6790                            procs.add(app);
6791                        }
6792                    }
6793                }
6794
6795                final int N = procs.size();
6796                for (int i = 0; i < N; i++) {
6797                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6798                }
6799            }
6800        } finally {
6801            Binder.restoreCallingIdentity(callingId);
6802        }
6803    }
6804
6805    @Override
6806    public void forceStopPackage(final String packageName, int userId) {
6807        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6808                != PackageManager.PERMISSION_GRANTED) {
6809            String msg = "Permission Denial: forceStopPackage() from pid="
6810                    + Binder.getCallingPid()
6811                    + ", uid=" + Binder.getCallingUid()
6812                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6813            Slog.w(TAG, msg);
6814            throw new SecurityException(msg);
6815        }
6816        final int callingPid = Binder.getCallingPid();
6817        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6818                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6819        long callingId = Binder.clearCallingIdentity();
6820        try {
6821            IPackageManager pm = AppGlobals.getPackageManager();
6822            synchronized(this) {
6823                int[] users = userId == UserHandle.USER_ALL
6824                        ? mUserController.getUsers() : new int[] { userId };
6825                for (int user : users) {
6826                    if (getPackageManagerInternalLocked().isPackageStateProtected(
6827                            packageName, user)) {
6828                        Slog.w(TAG, "Ignoring request to force stop protected package "
6829                                + packageName + " u" + user);
6830                        return;
6831                    }
6832
6833                    int pkgUid = -1;
6834                    try {
6835                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6836                                user);
6837                    } catch (RemoteException e) {
6838                    }
6839                    if (pkgUid == -1) {
6840                        Slog.w(TAG, "Invalid packageName: " + packageName);
6841                        continue;
6842                    }
6843                    try {
6844                        pm.setPackageStoppedState(packageName, true, user);
6845                    } catch (RemoteException e) {
6846                    } catch (IllegalArgumentException e) {
6847                        Slog.w(TAG, "Failed trying to unstop package "
6848                                + packageName + ": " + e);
6849                    }
6850                    if (mUserController.isUserRunning(user, 0)) {
6851                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6852                        finishForceStopPackageLocked(packageName, pkgUid);
6853                    }
6854                }
6855            }
6856        } finally {
6857            Binder.restoreCallingIdentity(callingId);
6858        }
6859    }
6860
6861    @Override
6862    public void addPackageDependency(String packageName) {
6863        synchronized (this) {
6864            int callingPid = Binder.getCallingPid();
6865            if (callingPid == myPid()) {
6866                //  Yeah, um, no.
6867                return;
6868            }
6869            ProcessRecord proc;
6870            synchronized (mPidsSelfLocked) {
6871                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6872            }
6873            if (proc != null) {
6874                if (proc.pkgDeps == null) {
6875                    proc.pkgDeps = new ArraySet<String>(1);
6876                }
6877                proc.pkgDeps.add(packageName);
6878            }
6879        }
6880    }
6881
6882    /*
6883     * The pkg name and app id have to be specified.
6884     */
6885    @Override
6886    public void killApplication(String pkg, int appId, int userId, String reason) {
6887        if (pkg == null) {
6888            return;
6889        }
6890        // Make sure the uid is valid.
6891        if (appId < 0) {
6892            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6893            return;
6894        }
6895        int callerUid = Binder.getCallingUid();
6896        // Only the system server can kill an application
6897        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6898            // Post an aysnc message to kill the application
6899            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6900            msg.arg1 = appId;
6901            msg.arg2 = userId;
6902            Bundle bundle = new Bundle();
6903            bundle.putString("pkg", pkg);
6904            bundle.putString("reason", reason);
6905            msg.obj = bundle;
6906            mHandler.sendMessage(msg);
6907        } else {
6908            throw new SecurityException(callerUid + " cannot kill pkg: " +
6909                    pkg);
6910        }
6911    }
6912
6913    @Override
6914    public void closeSystemDialogs(String reason) {
6915        enforceNotIsolatedCaller("closeSystemDialogs");
6916
6917        final int pid = Binder.getCallingPid();
6918        final int uid = Binder.getCallingUid();
6919        final long origId = Binder.clearCallingIdentity();
6920        try {
6921            synchronized (this) {
6922                // Only allow this from foreground processes, so that background
6923                // applications can't abuse it to prevent system UI from being shown.
6924                if (uid >= FIRST_APPLICATION_UID) {
6925                    ProcessRecord proc;
6926                    synchronized (mPidsSelfLocked) {
6927                        proc = mPidsSelfLocked.get(pid);
6928                    }
6929                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6930                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6931                                + " from background process " + proc);
6932                        return;
6933                    }
6934                }
6935                closeSystemDialogsLocked(reason);
6936            }
6937        } finally {
6938            Binder.restoreCallingIdentity(origId);
6939        }
6940    }
6941
6942    @GuardedBy("this")
6943    void closeSystemDialogsLocked(String reason) {
6944        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6945        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6946                | Intent.FLAG_RECEIVER_FOREGROUND);
6947        if (reason != null) {
6948            intent.putExtra("reason", reason);
6949        }
6950        mWindowManager.closeSystemDialogs(reason);
6951
6952        mStackSupervisor.closeSystemDialogsLocked();
6953
6954        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6955                OP_NONE, null, false, false,
6956                -1, SYSTEM_UID, UserHandle.USER_ALL);
6957    }
6958
6959    @Override
6960    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6961        enforceNotIsolatedCaller("getProcessMemoryInfo");
6962        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6963        for (int i=pids.length-1; i>=0; i--) {
6964            ProcessRecord proc;
6965            int oomAdj;
6966            synchronized (this) {
6967                synchronized (mPidsSelfLocked) {
6968                    proc = mPidsSelfLocked.get(pids[i]);
6969                    oomAdj = proc != null ? proc.setAdj : 0;
6970                }
6971            }
6972            infos[i] = new Debug.MemoryInfo();
6973            long startTime = SystemClock.currentThreadTimeMillis();
6974            Debug.getMemoryInfo(pids[i], infos[i]);
6975            long endTime = SystemClock.currentThreadTimeMillis();
6976            if (proc != null) {
6977                synchronized (this) {
6978                    if (proc.thread != null && proc.setAdj == oomAdj) {
6979                        // Record this for posterity if the process has been stable.
6980                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6981                                infos[i].getTotalUss(), infos[i].getTotalRss(), false,
6982                                ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
6983                                proc.pkgList);
6984                    }
6985                }
6986            }
6987        }
6988        return infos;
6989    }
6990
6991    @Override
6992    public long[] getProcessPss(int[] pids) {
6993        enforceNotIsolatedCaller("getProcessPss");
6994        long[] pss = new long[pids.length];
6995        for (int i=pids.length-1; i>=0; i--) {
6996            ProcessRecord proc;
6997            int oomAdj;
6998            synchronized (this) {
6999                synchronized (mPidsSelfLocked) {
7000                    proc = mPidsSelfLocked.get(pids[i]);
7001                    oomAdj = proc != null ? proc.setAdj : 0;
7002                }
7003            }
7004            long[] tmpUss = new long[3];
7005            long startTime = SystemClock.currentThreadTimeMillis();
7006            pss[i] = Debug.getPss(pids[i], tmpUss, null);
7007            long endTime = SystemClock.currentThreadTimeMillis();
7008            if (proc != null) {
7009                synchronized (this) {
7010                    if (proc.thread != null && proc.setAdj == oomAdj) {
7011                        // Record this for posterity if the process has been stable.
7012                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
7013                                ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
7014                    }
7015                }
7016            }
7017        }
7018        return pss;
7019    }
7020
7021    @Override
7022    public void killApplicationProcess(String processName, int uid) {
7023        if (processName == null) {
7024            return;
7025        }
7026
7027        int callerUid = Binder.getCallingUid();
7028        // Only the system server can kill an application
7029        if (callerUid == SYSTEM_UID) {
7030            synchronized (this) {
7031                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
7032                if (app != null && app.thread != null) {
7033                    try {
7034                        app.thread.scheduleSuicide();
7035                    } catch (RemoteException e) {
7036                        // If the other end already died, then our work here is done.
7037                    }
7038                } else {
7039                    Slog.w(TAG, "Process/uid not found attempting kill of "
7040                            + processName + " / " + uid);
7041                }
7042            }
7043        } else {
7044            throw new SecurityException(callerUid + " cannot kill app process: " +
7045                    processName);
7046        }
7047    }
7048
7049    @GuardedBy("this")
7050    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
7051        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
7052                false, true, false, false, UserHandle.getUserId(uid), reason);
7053    }
7054
7055    @GuardedBy("this")
7056    private void finishForceStopPackageLocked(final String packageName, int uid) {
7057        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
7058                Uri.fromParts("package", packageName, null));
7059        if (!mProcessesReady) {
7060            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7061                    | Intent.FLAG_RECEIVER_FOREGROUND);
7062        }
7063        intent.putExtra(Intent.EXTRA_UID, uid);
7064        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
7065        broadcastIntentLocked(null, null, intent,
7066                null, null, 0, null, null, null, OP_NONE,
7067                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
7068    }
7069
7070
7071    @GuardedBy("this")
7072    private final boolean killPackageProcessesLocked(String packageName, int appId,
7073            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
7074            boolean doit, boolean evenPersistent, String reason) {
7075        ArrayList<ProcessRecord> procs = new ArrayList<>();
7076
7077        // Remove all processes this package may have touched: all with the
7078        // same UID (except for the system or root user), and all whose name
7079        // matches the package name.
7080        final int NP = mProcessNames.getMap().size();
7081        for (int ip=0; ip<NP; ip++) {
7082            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
7083            final int NA = apps.size();
7084            for (int ia=0; ia<NA; ia++) {
7085                ProcessRecord app = apps.valueAt(ia);
7086                if (app.persistent && !evenPersistent) {
7087                    // we don't kill persistent processes
7088                    continue;
7089                }
7090                if (app.removed) {
7091                    if (doit) {
7092                        procs.add(app);
7093                    }
7094                    continue;
7095                }
7096
7097                // Skip process if it doesn't meet our oom adj requirement.
7098                if (app.setAdj < minOomAdj) {
7099                    continue;
7100                }
7101
7102                // If no package is specified, we call all processes under the
7103                // give user id.
7104                if (packageName == null) {
7105                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
7106                        continue;
7107                    }
7108                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
7109                        continue;
7110                    }
7111                // Package has been specified, we want to hit all processes
7112                // that match it.  We need to qualify this by the processes
7113                // that are running under the specified app and user ID.
7114                } else {
7115                    final boolean isDep = app.pkgDeps != null
7116                            && app.pkgDeps.contains(packageName);
7117                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
7118                        continue;
7119                    }
7120                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
7121                        continue;
7122                    }
7123                    if (!app.pkgList.containsKey(packageName) && !isDep) {
7124                        continue;
7125                    }
7126                }
7127
7128                // Process has passed all conditions, kill it!
7129                if (!doit) {
7130                    return true;
7131                }
7132                app.removed = true;
7133                procs.add(app);
7134            }
7135        }
7136
7137        int N = procs.size();
7138        for (int i=0; i<N; i++) {
7139            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
7140        }
7141        updateOomAdjLocked();
7142        return N > 0;
7143    }
7144
7145    private void cleanupDisabledPackageComponentsLocked(
7146            String packageName, int userId, boolean killProcess, String[] changedClasses) {
7147
7148        Set<String> disabledClasses = null;
7149        boolean packageDisabled = false;
7150        IPackageManager pm = AppGlobals.getPackageManager();
7151
7152        if (changedClasses == null) {
7153            // Nothing changed...
7154            return;
7155        }
7156
7157        // Determine enable/disable state of the package and its components.
7158        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
7159        for (int i = changedClasses.length - 1; i >= 0; i--) {
7160            final String changedClass = changedClasses[i];
7161
7162            if (changedClass.equals(packageName)) {
7163                try {
7164                    // Entire package setting changed
7165                    enabled = pm.getApplicationEnabledSetting(packageName,
7166                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
7167                } catch (Exception e) {
7168                    // No such package/component; probably racing with uninstall.  In any
7169                    // event it means we have nothing further to do here.
7170                    return;
7171                }
7172                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
7173                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
7174                if (packageDisabled) {
7175                    // Entire package is disabled.
7176                    // No need to continue to check component states.
7177                    disabledClasses = null;
7178                    break;
7179                }
7180            } else {
7181                try {
7182                    enabled = pm.getComponentEnabledSetting(
7183                            new ComponentName(packageName, changedClass),
7184                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
7185                } catch (Exception e) {
7186                    // As above, probably racing with uninstall.
7187                    return;
7188                }
7189                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
7190                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
7191                    if (disabledClasses == null) {
7192                        disabledClasses = new ArraySet<>(changedClasses.length);
7193                    }
7194                    disabledClasses.add(changedClass);
7195                }
7196            }
7197        }
7198
7199        if (!packageDisabled && disabledClasses == null) {
7200            // Nothing to do here...
7201            return;
7202        }
7203
7204        // Clean-up disabled activities.
7205        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7206                packageName, disabledClasses, true, false, userId) && mBooted) {
7207            mStackSupervisor.resumeFocusedStackTopActivityLocked();
7208            mStackSupervisor.scheduleIdleLocked();
7209        }
7210
7211        // Clean-up disabled tasks
7212        mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
7213
7214        // Clean-up disabled services.
7215        mServices.bringDownDisabledPackageServicesLocked(
7216                packageName, disabledClasses, userId, false, killProcess, true);
7217
7218        // Clean-up disabled providers.
7219        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7220        mProviderMap.collectPackageProvidersLocked(
7221                packageName, disabledClasses, true, false, userId, providers);
7222        for (int i = providers.size() - 1; i >= 0; i--) {
7223            removeDyingProviderLocked(null, providers.get(i), true);
7224        }
7225
7226        // Clean-up disabled broadcast receivers.
7227        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7228            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7229                    packageName, disabledClasses, userId, true);
7230        }
7231
7232    }
7233
7234    final boolean clearBroadcastQueueForUserLocked(int userId) {
7235        boolean didSomething = false;
7236        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7237            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7238                    null, null, userId, true);
7239        }
7240        return didSomething;
7241    }
7242
7243    @GuardedBy("this")
7244    final boolean forceStopPackageLocked(String packageName, int appId,
7245            boolean callerWillRestart, boolean purgeCache, boolean doit,
7246            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
7247        int i;
7248
7249        if (userId == UserHandle.USER_ALL && packageName == null) {
7250            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
7251        }
7252
7253        if (appId < 0 && packageName != null) {
7254            try {
7255                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
7256                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
7257            } catch (RemoteException e) {
7258            }
7259        }
7260
7261        if (doit) {
7262            if (packageName != null) {
7263                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
7264                        + " user=" + userId + ": " + reason);
7265            } else {
7266                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
7267            }
7268
7269            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
7270        }
7271
7272        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
7273                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
7274                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
7275
7276        didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
7277
7278        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7279                packageName, null, doit, evenPersistent, userId)) {
7280            if (!doit) {
7281                return true;
7282            }
7283            didSomething = true;
7284        }
7285
7286        if (mServices.bringDownDisabledPackageServicesLocked(
7287                packageName, null, userId, evenPersistent, true, doit)) {
7288            if (!doit) {
7289                return true;
7290            }
7291            didSomething = true;
7292        }
7293
7294        if (packageName == null) {
7295            // Remove all sticky broadcasts from this user.
7296            mStickyBroadcasts.remove(userId);
7297        }
7298
7299        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7300        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
7301                userId, providers)) {
7302            if (!doit) {
7303                return true;
7304            }
7305            didSomething = true;
7306        }
7307        for (i = providers.size() - 1; i >= 0; i--) {
7308            removeDyingProviderLocked(null, providers.get(i), true);
7309        }
7310
7311        // Remove transient permissions granted from/to this package/user
7312        removeUriPermissionsForPackageLocked(packageName, userId, false, false);
7313
7314        if (doit) {
7315            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
7316                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7317                        packageName, null, userId, doit);
7318            }
7319        }
7320
7321        if (packageName == null || uninstalling) {
7322            // Remove pending intents.  For now we only do this when force
7323            // stopping users, because we have some problems when doing this
7324            // for packages -- app widgets are not currently cleaned up for
7325            // such packages, so they can be left with bad pending intents.
7326            if (mIntentSenderRecords.size() > 0) {
7327                Iterator<WeakReference<PendingIntentRecord>> it
7328                        = mIntentSenderRecords.values().iterator();
7329                while (it.hasNext()) {
7330                    WeakReference<PendingIntentRecord> wpir = it.next();
7331                    if (wpir == null) {
7332                        it.remove();
7333                        continue;
7334                    }
7335                    PendingIntentRecord pir = wpir.get();
7336                    if (pir == null) {
7337                        it.remove();
7338                        continue;
7339                    }
7340                    if (packageName == null) {
7341                        // Stopping user, remove all objects for the user.
7342                        if (pir.key.userId != userId) {
7343                            // Not the same user, skip it.
7344                            continue;
7345                        }
7346                    } else {
7347                        if (UserHandle.getAppId(pir.uid) != appId) {
7348                            // Different app id, skip it.
7349                            continue;
7350                        }
7351                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
7352                            // Different user, skip it.
7353                            continue;
7354                        }
7355                        if (!pir.key.packageName.equals(packageName)) {
7356                            // Different package, skip it.
7357                            continue;
7358                        }
7359                    }
7360                    if (!doit) {
7361                        return true;
7362                    }
7363                    didSomething = true;
7364                    it.remove();
7365                    makeIntentSenderCanceledLocked(pir);
7366                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
7367                        pir.key.activity.pendingResults.remove(pir.ref);
7368                    }
7369                }
7370            }
7371        }
7372
7373        if (doit) {
7374            if (purgeCache && packageName != null) {
7375                AttributeCache ac = AttributeCache.instance();
7376                if (ac != null) {
7377                    ac.removePackage(packageName);
7378                }
7379            }
7380            if (mBooted) {
7381                mStackSupervisor.resumeFocusedStackTopActivityLocked();
7382                mStackSupervisor.scheduleIdleLocked();
7383            }
7384        }
7385
7386        return didSomething;
7387    }
7388
7389    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
7390        return removeProcessNameLocked(name, uid, null);
7391    }
7392
7393    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
7394            final ProcessRecord expecting) {
7395        ProcessRecord old = mProcessNames.get(name, uid);
7396        // Only actually remove when the currently recorded value matches the
7397        // record that we expected; if it doesn't match then we raced with a
7398        // newly created process and we don't want to destroy the new one.
7399        if ((expecting == null) || (old == expecting)) {
7400            mProcessNames.remove(name, uid);
7401        }
7402        if (old != null && old.uidRecord != null) {
7403            old.uidRecord.numProcs--;
7404            if (old.uidRecord.numProcs == 0) {
7405                // No more processes using this uid, tell clients it is gone.
7406                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7407                        "No more processes in " + old.uidRecord);
7408                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
7409                EventLogTags.writeAmUidStopped(uid);
7410                mActiveUids.remove(uid);
7411                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
7412            }
7413            old.uidRecord = null;
7414        }
7415        mIsolatedProcesses.remove(uid);
7416        return old;
7417    }
7418
7419    private final void addProcessNameLocked(ProcessRecord proc) {
7420        // We shouldn't already have a process under this name, but just in case we
7421        // need to clean up whatever may be there now.
7422        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
7423        if (old == proc && proc.persistent) {
7424            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
7425            Slog.w(TAG, "Re-adding persistent process " + proc);
7426        } else if (old != null) {
7427            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
7428        }
7429        UidRecord uidRec = mActiveUids.get(proc.uid);
7430        if (uidRec == null) {
7431            uidRec = new UidRecord(proc.uid);
7432            // This is the first appearance of the uid, report it now!
7433            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7434                    "Creating new process uid: " + uidRec);
7435            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
7436                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
7437                uidRec.setWhitelist = uidRec.curWhitelist = true;
7438            }
7439            uidRec.updateHasInternetPermission();
7440            mActiveUids.put(proc.uid, uidRec);
7441            EventLogTags.writeAmUidRunning(uidRec.uid);
7442            noteUidProcessState(uidRec.uid, uidRec.curProcState);
7443        }
7444        proc.uidRecord = uidRec;
7445
7446        // Reset render thread tid if it was already set, so new process can set it again.
7447        proc.renderThreadTid = 0;
7448        uidRec.numProcs++;
7449        mProcessNames.put(proc.processName, proc.uid, proc);
7450        if (proc.isolated) {
7451            mIsolatedProcesses.put(proc.uid, proc);
7452        }
7453    }
7454
7455    @GuardedBy("this")
7456    boolean removeProcessLocked(ProcessRecord app,
7457            boolean callerWillRestart, boolean allowRestart, String reason) {
7458        final String name = app.processName;
7459        final int uid = app.uid;
7460        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
7461            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
7462
7463        ProcessRecord old = mProcessNames.get(name, uid);
7464        if (old != app) {
7465            // This process is no longer active, so nothing to do.
7466            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
7467            return false;
7468        }
7469        removeProcessNameLocked(name, uid);
7470        if (mHeavyWeightProcess == app) {
7471            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7472                    mHeavyWeightProcess.userId, 0));
7473            mHeavyWeightProcess = null;
7474        }
7475        boolean needRestart = false;
7476        if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
7477            int pid = app.pid;
7478            if (pid > 0) {
7479                synchronized (mPidsSelfLocked) {
7480                    mPidsSelfLocked.remove(pid);
7481                    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7482                }
7483                mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7484                if (app.isolated) {
7485                    mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7486                    getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
7487                }
7488            }
7489            boolean willRestart = false;
7490            if (app.persistent && !app.isolated) {
7491                if (!callerWillRestart) {
7492                    willRestart = true;
7493                } else {
7494                    needRestart = true;
7495                }
7496            }
7497            app.kill(reason, true);
7498            handleAppDiedLocked(app, willRestart, allowRestart);
7499            if (willRestart) {
7500                removeLruProcessLocked(app);
7501                addAppLocked(app.info, null, false, null /* ABI override */);
7502            }
7503        } else {
7504            mRemovedProcesses.add(app);
7505        }
7506
7507        return needRestart;
7508    }
7509
7510    @GuardedBy("this")
7511    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
7512        cleanupAppInLaunchingProvidersLocked(app, true);
7513        removeProcessLocked(app, false, true, "timeout publishing content providers");
7514    }
7515
7516    private final void processStartTimedOutLocked(ProcessRecord app) {
7517        final int pid = app.pid;
7518        boolean gone = false;
7519        synchronized (mPidsSelfLocked) {
7520            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
7521            if (knownApp != null && knownApp.thread == null) {
7522                mPidsSelfLocked.remove(pid);
7523                gone = true;
7524            }
7525        }
7526
7527        if (gone) {
7528            Slog.w(TAG, "Process " + app + " failed to attach");
7529            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
7530                    pid, app.uid, app.processName);
7531            removeProcessNameLocked(app.processName, app.uid);
7532            if (mHeavyWeightProcess == app) {
7533                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7534                        mHeavyWeightProcess.userId, 0));
7535                mHeavyWeightProcess = null;
7536            }
7537            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7538            // Take care of any launching providers waiting for this process.
7539            cleanupAppInLaunchingProvidersLocked(app, true);
7540            // Take care of any services that are waiting for the process.
7541            mServices.processStartTimedOutLocked(app);
7542            app.kill("start timeout", true);
7543            if (app.isolated) {
7544                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7545            }
7546            removeLruProcessLocked(app);
7547            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
7548                Slog.w(TAG, "Unattached app died before backup, skipping");
7549                mHandler.post(new Runnable() {
7550                @Override
7551                    public void run(){
7552                        try {
7553                            IBackupManager bm = IBackupManager.Stub.asInterface(
7554                                    ServiceManager.getService(Context.BACKUP_SERVICE));
7555                            bm.agentDisconnected(app.info.packageName);
7556                        } catch (RemoteException e) {
7557                            // Can't happen; the backup manager is local
7558                        }
7559                    }
7560                });
7561            }
7562            if (isPendingBroadcastProcessLocked(pid)) {
7563                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
7564                skipPendingBroadcastLocked(pid);
7565            }
7566        } else {
7567            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
7568        }
7569    }
7570
7571    @GuardedBy("this")
7572    private final boolean attachApplicationLocked(IApplicationThread thread,
7573            int pid, int callingUid, long startSeq) {
7574
7575        // Find the application record that is being attached...  either via
7576        // the pid if we are running in multiple processes, or just pull the
7577        // next app record if we are emulating process with anonymous threads.
7578        ProcessRecord app;
7579        long startTime = SystemClock.uptimeMillis();
7580        if (pid != MY_PID && pid >= 0) {
7581            synchronized (mPidsSelfLocked) {
7582                app = mPidsSelfLocked.get(pid);
7583            }
7584        } else {
7585            app = null;
7586        }
7587
7588        // It's possible that process called attachApplication before we got a chance to
7589        // update the internal state.
7590        if (app == null && startSeq > 0) {
7591            final ProcessRecord pending = mPendingStarts.get(startSeq);
7592            if (pending != null && pending.startUid == callingUid
7593                    && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
7594                            startSeq, true)) {
7595                app = pending;
7596            }
7597        }
7598
7599        if (app == null) {
7600            Slog.w(TAG, "No pending application record for pid " + pid
7601                    + " (IApplicationThread " + thread + "); dropping process");
7602            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
7603            if (pid > 0 && pid != MY_PID) {
7604                killProcessQuiet(pid);
7605                //TODO: killProcessGroup(app.info.uid, pid);
7606            } else {
7607                try {
7608                    thread.scheduleExit();
7609                } catch (Exception e) {
7610                    // Ignore exceptions.
7611                }
7612            }
7613            return false;
7614        }
7615
7616        // If this application record is still attached to a previous
7617        // process, clean it up now.
7618        if (app.thread != null) {
7619            handleAppDiedLocked(app, true, true);
7620        }
7621
7622        // Tell the process all about itself.
7623
7624        if (DEBUG_ALL) Slog.v(
7625                TAG, "Binding process pid " + pid + " to record " + app);
7626
7627        final String processName = app.processName;
7628        try {
7629            AppDeathRecipient adr = new AppDeathRecipient(
7630                    app, pid, thread);
7631            thread.asBinder().linkToDeath(adr, 0);
7632            app.deathRecipient = adr;
7633        } catch (RemoteException e) {
7634            app.resetPackageList(mProcessStats);
7635            startProcessLocked(app, "link fail", processName);
7636            return false;
7637        }
7638
7639        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
7640
7641        app.makeActive(thread, mProcessStats);
7642        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
7643        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
7644        app.forcingToImportant = null;
7645        updateProcessForegroundLocked(app, false, false);
7646        app.hasShownUi = false;
7647        app.debugging = false;
7648        app.cached = false;
7649        app.killedByAm = false;
7650        app.killed = false;
7651
7652
7653        // We carefully use the same state that PackageManager uses for
7654        // filtering, since we use this flag to decide if we need to install
7655        // providers when user is unlocked later
7656        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
7657
7658        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7659
7660        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
7661        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7662
7663        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7664            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7665            msg.obj = app;
7666            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7667        }
7668
7669        checkTime(startTime, "attachApplicationLocked: before bindApplication");
7670
7671        if (!normalMode) {
7672            Slog.i(TAG, "Launching preboot mode app: " + app);
7673        }
7674
7675        if (DEBUG_ALL) Slog.v(
7676            TAG, "New app record " + app
7677            + " thread=" + thread.asBinder() + " pid=" + pid);
7678        try {
7679            int testMode = ApplicationThreadConstants.DEBUG_OFF;
7680            if (mDebugApp != null && mDebugApp.equals(processName)) {
7681                testMode = mWaitForDebugger
7682                    ? ApplicationThreadConstants.DEBUG_WAIT
7683                    : ApplicationThreadConstants.DEBUG_ON;
7684                app.debugging = true;
7685                if (mDebugTransient) {
7686                    mDebugApp = mOrigDebugApp;
7687                    mWaitForDebugger = mOrigWaitForDebugger;
7688                }
7689            }
7690
7691            boolean enableTrackAllocation = false;
7692            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7693                enableTrackAllocation = true;
7694                mTrackAllocationApp = null;
7695            }
7696
7697            // If the app is being launched for restore or full backup, set it up specially
7698            boolean isRestrictedBackupMode = false;
7699            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7700                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7701                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7702                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7703                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7704            }
7705
7706            if (app.instr != null) {
7707                notifyPackageUse(app.instr.mClass.getPackageName(),
7708                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7709            }
7710            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7711                    + processName + " with config " + getGlobalConfiguration());
7712            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7713            app.compat = compatibilityInfoForPackageLocked(appInfo);
7714
7715            ProfilerInfo profilerInfo = null;
7716            String preBindAgent = null;
7717            if (mProfileApp != null && mProfileApp.equals(processName)) {
7718                mProfileProc = app;
7719                if (mProfilerInfo != null) {
7720                    // Send a profiler info object to the app if either a file is given, or
7721                    // an agent should be loaded at bind-time.
7722                    boolean needsInfo = mProfilerInfo.profileFile != null
7723                            || mProfilerInfo.attachAgentDuringBind;
7724                    profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7725                    if (mProfilerInfo.agent != null) {
7726                        preBindAgent = mProfilerInfo.agent;
7727                    }
7728                }
7729            } else if (app.instr != null && app.instr.mProfileFile != null) {
7730                profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7731                        null, false);
7732            }
7733            if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
7734                // We need to do a debuggable check here. See setAgentApp for why the check is
7735                // postponed to here.
7736                if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
7737                    String agent = mAppAgentMap.get(processName);
7738                    // Do not overwrite already requested agent.
7739                    if (profilerInfo == null) {
7740                        profilerInfo = new ProfilerInfo(null, null, 0, false, false,
7741                                mAppAgentMap.get(processName), true);
7742                    } else if (profilerInfo.agent == null) {
7743                        profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
7744                    }
7745                }
7746            }
7747
7748            if (profilerInfo != null && profilerInfo.profileFd != null) {
7749                profilerInfo.profileFd = profilerInfo.profileFd.dup();
7750                if (TextUtils.equals(mProfileApp, processName) && mProfilerInfo != null) {
7751                    clearProfilerLocked();
7752                }
7753            }
7754
7755            // We deprecated Build.SERIAL and it is not accessible to
7756            // apps that target the v2 security sandbox and to apps that
7757            // target APIs higher than O MR1. Since access to the serial
7758            // is now behind a permission we push down the value.
7759            final String buildSerial = (appInfo.targetSandboxVersion < 2
7760                    && appInfo.targetSdkVersion < Build.VERSION_CODES.P)
7761                            ? sTheRealBuildSerial : Build.UNKNOWN;
7762
7763            // Check if this is a secondary process that should be incorporated into some
7764            // currently active instrumentation.  (Note we do this AFTER all of the profiling
7765            // stuff above because profiling can currently happen only in the primary
7766            // instrumentation process.)
7767            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7768                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7769                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7770                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7771                        if (aInstr.mTargetProcesses.length == 0) {
7772                            // This is the wildcard mode, where every process brought up for
7773                            // the target instrumentation should be included.
7774                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7775                                app.instr = aInstr;
7776                                aInstr.mRunningProcesses.add(app);
7777                            }
7778                        } else {
7779                            for (String proc : aInstr.mTargetProcesses) {
7780                                if (proc.equals(app.processName)) {
7781                                    app.instr = aInstr;
7782                                    aInstr.mRunningProcesses.add(app);
7783                                    break;
7784                                }
7785                            }
7786                        }
7787                    }
7788                }
7789            }
7790
7791            // If we were asked to attach an agent on startup, do so now, before we're binding
7792            // application code.
7793            if (preBindAgent != null) {
7794                thread.attachAgent(preBindAgent);
7795            }
7796
7797
7798            // Figure out whether the app needs to run in autofill compat mode.
7799            boolean isAutofillCompatEnabled = false;
7800            if (UserHandle.getAppId(app.info.uid) >= Process.FIRST_APPLICATION_UID) {
7801                final AutofillManagerInternal afm = LocalServices.getService(
7802                        AutofillManagerInternal.class);
7803                if (afm != null) {
7804                    isAutofillCompatEnabled = afm.isCompatibilityModeRequested(
7805                            app.info.packageName, app.info.versionCode, app.userId);
7806                }
7807            }
7808
7809            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7810            mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
7811            if (app.isolatedEntryPoint != null) {
7812                // This is an isolated process which should just call an entry point instead of
7813                // being bound to an application.
7814                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7815            } else if (app.instr != null) {
7816                thread.bindApplication(processName, appInfo, providers,
7817                        app.instr.mClass,
7818                        profilerInfo, app.instr.mArguments,
7819                        app.instr.mWatcher,
7820                        app.instr.mUiAutomationConnection, testMode,
7821                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7822                        isRestrictedBackupMode || !normalMode, app.persistent,
7823                        new Configuration(getGlobalConfiguration()), app.compat,
7824                        getCommonServicesLocked(app.isolated),
7825                        mCoreSettingsObserver.getCoreSettingsLocked(),
7826                        buildSerial, isAutofillCompatEnabled);
7827            } else {
7828                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7829                        null, null, null, testMode,
7830                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7831                        isRestrictedBackupMode || !normalMode, app.persistent,
7832                        new Configuration(getGlobalConfiguration()), app.compat,
7833                        getCommonServicesLocked(app.isolated),
7834                        mCoreSettingsObserver.getCoreSettingsLocked(),
7835                        buildSerial, isAutofillCompatEnabled);
7836            }
7837            if (profilerInfo != null) {
7838                profilerInfo.closeFd();
7839                profilerInfo = null;
7840            }
7841            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7842            updateLruProcessLocked(app, false, null);
7843            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7844            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7845        } catch (Exception e) {
7846            // todo: Yikes!  What should we do?  For now we will try to
7847            // start another process, but that could easily get us in
7848            // an infinite loop of restarting processes...
7849            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7850
7851            app.resetPackageList(mProcessStats);
7852            app.unlinkDeathRecipient();
7853            startProcessLocked(app, "bind fail", processName);
7854            return false;
7855        }
7856
7857        // Remove this record from the list of starting applications.
7858        mPersistentStartingProcesses.remove(app);
7859        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7860                "Attach application locked removing on hold: " + app);
7861        mProcessesOnHold.remove(app);
7862
7863        boolean badApp = false;
7864        boolean didSomething = false;
7865
7866        // See if the top visible activity is waiting to run in this process...
7867        if (normalMode) {
7868            try {
7869                if (mStackSupervisor.attachApplicationLocked(app)) {
7870                    didSomething = true;
7871                }
7872            } catch (Exception e) {
7873                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7874                badApp = true;
7875            }
7876        }
7877
7878        // Find any services that should be running in this process...
7879        if (!badApp) {
7880            try {
7881                didSomething |= mServices.attachApplicationLocked(app, processName);
7882                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7883            } catch (Exception e) {
7884                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7885                badApp = true;
7886            }
7887        }
7888
7889        // Check if a next-broadcast receiver is in this process...
7890        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7891            try {
7892                didSomething |= sendPendingBroadcastsLocked(app);
7893                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7894            } catch (Exception e) {
7895                // If the app died trying to launch the receiver we declare it 'bad'
7896                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7897                badApp = true;
7898            }
7899        }
7900
7901        // Check whether the next backup agent is in this process...
7902        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7903            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7904                    "New app is backup target, launching agent for " + app);
7905            notifyPackageUse(mBackupTarget.appInfo.packageName,
7906                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7907            try {
7908                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7909                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7910                        mBackupTarget.backupMode);
7911            } catch (Exception e) {
7912                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7913                badApp = true;
7914            }
7915        }
7916
7917        if (badApp) {
7918            app.kill("error during init", true);
7919            handleAppDiedLocked(app, false, true);
7920            return false;
7921        }
7922
7923        if (!didSomething) {
7924            updateOomAdjLocked();
7925            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7926        }
7927
7928        return true;
7929    }
7930
7931    @Override
7932    public final void attachApplication(IApplicationThread thread, long startSeq) {
7933        synchronized (this) {
7934            int callingPid = Binder.getCallingPid();
7935            final int callingUid = Binder.getCallingUid();
7936            final long origId = Binder.clearCallingIdentity();
7937            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
7938            Binder.restoreCallingIdentity(origId);
7939        }
7940    }
7941
7942    @Override
7943    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7944        final long origId = Binder.clearCallingIdentity();
7945        synchronized (this) {
7946            ActivityStack stack = ActivityRecord.getStackLocked(token);
7947            if (stack != null) {
7948                ActivityRecord r =
7949                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7950                                false /* processPausingActivities */, config);
7951                if (stopProfiling) {
7952                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
7953                        clearProfilerLocked();
7954                    }
7955                }
7956            }
7957        }
7958        Binder.restoreCallingIdentity(origId);
7959    }
7960
7961    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7962        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7963                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7964    }
7965
7966    void enableScreenAfterBoot() {
7967        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7968                SystemClock.uptimeMillis());
7969        mWindowManager.enableScreenAfterBoot();
7970
7971        synchronized (this) {
7972            updateEventDispatchingLocked();
7973        }
7974    }
7975
7976    @Override
7977    public void showBootMessage(final CharSequence msg, final boolean always) {
7978        if (Binder.getCallingUid() != myUid()) {
7979            throw new SecurityException();
7980        }
7981        mWindowManager.showBootMessage(msg, always);
7982    }
7983
7984    @Override
7985    public void keyguardGoingAway(int flags) {
7986        enforceNotIsolatedCaller("keyguardGoingAway");
7987        final long token = Binder.clearCallingIdentity();
7988        try {
7989            synchronized (this) {
7990                mKeyguardController.keyguardGoingAway(flags);
7991            }
7992        } finally {
7993            Binder.restoreCallingIdentity(token);
7994        }
7995    }
7996
7997    /**
7998     * @return whther the keyguard is currently locked.
7999     */
8000    boolean isKeyguardLocked() {
8001        return mKeyguardController.isKeyguardLocked();
8002    }
8003
8004    final void finishBooting() {
8005        synchronized (this) {
8006            if (!mBootAnimationComplete) {
8007                mCallFinishBooting = true;
8008                return;
8009            }
8010            mCallFinishBooting = false;
8011        }
8012
8013        ArraySet<String> completedIsas = new ArraySet<String>();
8014        for (String abi : Build.SUPPORTED_ABIS) {
8015            zygoteProcess.establishZygoteConnectionForAbi(abi);
8016            final String instructionSet = VMRuntime.getInstructionSet(abi);
8017            if (!completedIsas.contains(instructionSet)) {
8018                try {
8019                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
8020                } catch (InstallerException e) {
8021                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
8022                            e.getMessage() +")");
8023                }
8024                completedIsas.add(instructionSet);
8025            }
8026        }
8027
8028        IntentFilter pkgFilter = new IntentFilter();
8029        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
8030        pkgFilter.addDataScheme("package");
8031        mContext.registerReceiver(new BroadcastReceiver() {
8032            @Override
8033            public void onReceive(Context context, Intent intent) {
8034                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
8035                if (pkgs != null) {
8036                    for (String pkg : pkgs) {
8037                        synchronized (ActivityManagerService.this) {
8038                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
8039                                    0, "query restart")) {
8040                                setResultCode(Activity.RESULT_OK);
8041                                return;
8042                            }
8043                        }
8044                    }
8045                }
8046            }
8047        }, pkgFilter);
8048
8049        IntentFilter dumpheapFilter = new IntentFilter();
8050        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
8051        mContext.registerReceiver(new BroadcastReceiver() {
8052            @Override
8053            public void onReceive(Context context, Intent intent) {
8054                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
8055                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
8056                } else {
8057                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
8058                }
8059            }
8060        }, dumpheapFilter);
8061
8062        // Let system services know.
8063        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
8064
8065        synchronized (this) {
8066            // Ensure that any processes we had put on hold are now started
8067            // up.
8068            final int NP = mProcessesOnHold.size();
8069            if (NP > 0) {
8070                ArrayList<ProcessRecord> procs =
8071                    new ArrayList<ProcessRecord>(mProcessesOnHold);
8072                for (int ip=0; ip<NP; ip++) {
8073                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
8074                            + procs.get(ip));
8075                    startProcessLocked(procs.get(ip), "on-hold", null);
8076                }
8077            }
8078            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
8079                return;
8080            }
8081            // Start looking for apps that are abusing wake locks.
8082            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
8083            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
8084            // Tell anyone interested that we are done booting!
8085            SystemProperties.set("sys.boot_completed", "1");
8086
8087            // And trigger dev.bootcomplete if we are not showing encryption progress
8088            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
8089                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
8090                SystemProperties.set("dev.bootcomplete", "1");
8091            }
8092            mUserController.sendBootCompleted(
8093                    new IIntentReceiver.Stub() {
8094                        @Override
8095                        public void performReceive(Intent intent, int resultCode,
8096                                String data, Bundle extras, boolean ordered,
8097                                boolean sticky, int sendingUser) {
8098                            synchronized (ActivityManagerService.this) {
8099                                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
8100                            }
8101                        }
8102                    });
8103            mUserController.scheduleStartProfiles();
8104        }
8105    }
8106
8107    @Override
8108    public void bootAnimationComplete() {
8109        final boolean callFinishBooting;
8110        synchronized (this) {
8111            callFinishBooting = mCallFinishBooting;
8112            mBootAnimationComplete = true;
8113        }
8114        if (callFinishBooting) {
8115            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
8116            finishBooting();
8117            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
8118        }
8119    }
8120
8121    final void ensureBootCompleted() {
8122        boolean booting;
8123        boolean enableScreen;
8124        synchronized (this) {
8125            booting = mBooting;
8126            mBooting = false;
8127            enableScreen = !mBooted;
8128            mBooted = true;
8129        }
8130
8131        if (booting) {
8132            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
8133            finishBooting();
8134            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
8135        }
8136
8137        if (enableScreen) {
8138            enableScreenAfterBoot();
8139        }
8140    }
8141
8142    @Override
8143    public final void activityResumed(IBinder token) {
8144        final long origId = Binder.clearCallingIdentity();
8145        synchronized(this) {
8146            ActivityRecord.activityResumedLocked(token);
8147            mWindowManager.notifyAppResumedFinished(token);
8148        }
8149        Binder.restoreCallingIdentity(origId);
8150    }
8151
8152    @Override
8153    public final void activityPaused(IBinder token) {
8154        final long origId = Binder.clearCallingIdentity();
8155        synchronized(this) {
8156            ActivityStack stack = ActivityRecord.getStackLocked(token);
8157            if (stack != null) {
8158                stack.activityPausedLocked(token, false);
8159            }
8160        }
8161        Binder.restoreCallingIdentity(origId);
8162    }
8163
8164    @Override
8165    public final void activityStopped(IBinder token, Bundle icicle,
8166            PersistableBundle persistentState, CharSequence description) {
8167        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
8168
8169        // Refuse possible leaked file descriptors
8170        if (icicle != null && icicle.hasFileDescriptors()) {
8171            throw new IllegalArgumentException("File descriptors passed in Bundle");
8172        }
8173
8174        final long origId = Binder.clearCallingIdentity();
8175
8176        synchronized (this) {
8177            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8178            if (r != null) {
8179                r.activityStoppedLocked(icicle, persistentState, description);
8180            }
8181        }
8182
8183        trimApplications();
8184
8185        Binder.restoreCallingIdentity(origId);
8186    }
8187
8188    @Override
8189    public final void activityDestroyed(IBinder token) {
8190        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
8191        synchronized (this) {
8192            ActivityStack stack = ActivityRecord.getStackLocked(token);
8193            if (stack != null) {
8194                stack.activityDestroyedLocked(token, "activityDestroyed");
8195            }
8196        }
8197    }
8198
8199    @Override
8200    public final void activityRelaunched(IBinder token) {
8201        final long origId = Binder.clearCallingIdentity();
8202        synchronized (this) {
8203            mStackSupervisor.activityRelaunchedLocked(token);
8204        }
8205        Binder.restoreCallingIdentity(origId);
8206    }
8207
8208    @Override
8209    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
8210            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
8211        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
8212                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
8213        synchronized (this) {
8214            ActivityRecord record = ActivityRecord.isInStackLocked(token);
8215            if (record == null) {
8216                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
8217                        + "found for: " + token);
8218            }
8219            record.setSizeConfigurations(horizontalSizeConfiguration,
8220                    verticalSizeConfigurations, smallestSizeConfigurations);
8221        }
8222    }
8223
8224    @Override
8225    public final void notifyLaunchTaskBehindComplete(IBinder token) {
8226        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
8227    }
8228
8229    @Override
8230    public final void notifyEnterAnimationComplete(IBinder token) {
8231        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
8232    }
8233
8234    @Override
8235    public String getCallingPackage(IBinder token) {
8236        synchronized (this) {
8237            ActivityRecord r = getCallingRecordLocked(token);
8238            return r != null ? r.info.packageName : null;
8239        }
8240    }
8241
8242    @Override
8243    public ComponentName getCallingActivity(IBinder token) {
8244        synchronized (this) {
8245            ActivityRecord r = getCallingRecordLocked(token);
8246            return r != null ? r.intent.getComponent() : null;
8247        }
8248    }
8249
8250    private ActivityRecord getCallingRecordLocked(IBinder token) {
8251        ActivityRecord r = ActivityRecord.isInStackLocked(token);
8252        if (r == null) {
8253            return null;
8254        }
8255        return r.resultTo;
8256    }
8257
8258    @Override
8259    public ComponentName getActivityClassForToken(IBinder token) {
8260        synchronized(this) {
8261            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8262            if (r == null) {
8263                return null;
8264            }
8265            return r.intent.getComponent();
8266        }
8267    }
8268
8269    @Override
8270    public String getPackageForToken(IBinder token) {
8271        synchronized(this) {
8272            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8273            if (r == null) {
8274                return null;
8275            }
8276            return r.packageName;
8277        }
8278    }
8279
8280    @Override
8281    public boolean isRootVoiceInteraction(IBinder token) {
8282        synchronized(this) {
8283            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8284            if (r == null) {
8285                return false;
8286            }
8287            return r.rootVoiceInteraction;
8288        }
8289    }
8290
8291    @Override
8292    public IIntentSender getIntentSender(int type,
8293            String packageName, IBinder token, String resultWho,
8294            int requestCode, Intent[] intents, String[] resolvedTypes,
8295            int flags, Bundle bOptions, int userId) {
8296        enforceNotIsolatedCaller("getIntentSender");
8297        // Refuse possible leaked file descriptors
8298        if (intents != null) {
8299            if (intents.length < 1) {
8300                throw new IllegalArgumentException("Intents array length must be >= 1");
8301            }
8302            for (int i=0; i<intents.length; i++) {
8303                Intent intent = intents[i];
8304                if (intent != null) {
8305                    if (intent.hasFileDescriptors()) {
8306                        throw new IllegalArgumentException("File descriptors passed in Intent");
8307                    }
8308                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
8309                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
8310                        throw new IllegalArgumentException(
8311                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
8312                    }
8313                    intents[i] = new Intent(intent);
8314                }
8315            }
8316            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
8317                throw new IllegalArgumentException(
8318                        "Intent array length does not match resolvedTypes length");
8319            }
8320        }
8321        if (bOptions != null) {
8322            if (bOptions.hasFileDescriptors()) {
8323                throw new IllegalArgumentException("File descriptors passed in options");
8324            }
8325        }
8326
8327        synchronized(this) {
8328            int callingUid = Binder.getCallingUid();
8329            int origUserId = userId;
8330            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8331                    type == ActivityManager.INTENT_SENDER_BROADCAST,
8332                    ALLOW_NON_FULL, "getIntentSender", null);
8333            if (origUserId == UserHandle.USER_CURRENT) {
8334                // We don't want to evaluate this until the pending intent is
8335                // actually executed.  However, we do want to always do the
8336                // security checking for it above.
8337                userId = UserHandle.USER_CURRENT;
8338            }
8339            try {
8340                if (callingUid != 0 && callingUid != SYSTEM_UID) {
8341                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
8342                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
8343                    if (!UserHandle.isSameApp(callingUid, uid)) {
8344                        String msg = "Permission Denial: getIntentSender() from pid="
8345                            + Binder.getCallingPid()
8346                            + ", uid=" + Binder.getCallingUid()
8347                            + ", (need uid=" + uid + ")"
8348                            + " is not allowed to send as package " + packageName;
8349                        Slog.w(TAG, msg);
8350                        throw new SecurityException(msg);
8351                    }
8352                }
8353
8354                return getIntentSenderLocked(type, packageName, callingUid, userId,
8355                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
8356
8357            } catch (RemoteException e) {
8358                throw new SecurityException(e);
8359            }
8360        }
8361    }
8362
8363    IIntentSender getIntentSenderLocked(int type, String packageName,
8364            int callingUid, int userId, IBinder token, String resultWho,
8365            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
8366            Bundle bOptions) {
8367        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
8368        ActivityRecord activity = null;
8369        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8370            activity = ActivityRecord.isInStackLocked(token);
8371            if (activity == null) {
8372                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
8373                return null;
8374            }
8375            if (activity.finishing) {
8376                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
8377                return null;
8378            }
8379        }
8380
8381        // We're going to be splicing together extras before sending, so we're
8382        // okay poking into any contained extras.
8383        if (intents != null) {
8384            for (int i = 0; i < intents.length; i++) {
8385                intents[i].setDefusable(true);
8386            }
8387        }
8388        Bundle.setDefusable(bOptions, true);
8389
8390        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
8391        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
8392        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
8393        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
8394                |PendingIntent.FLAG_UPDATE_CURRENT);
8395
8396        PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity,
8397                resultWho, requestCode, intents, resolvedTypes, flags,
8398                SafeActivityOptions.fromBundle(bOptions), userId);
8399        WeakReference<PendingIntentRecord> ref;
8400        ref = mIntentSenderRecords.get(key);
8401        PendingIntentRecord rec = ref != null ? ref.get() : null;
8402        if (rec != null) {
8403            if (!cancelCurrent) {
8404                if (updateCurrent) {
8405                    if (rec.key.requestIntent != null) {
8406                        rec.key.requestIntent.replaceExtras(intents != null ?
8407                                intents[intents.length - 1] : null);
8408                    }
8409                    if (intents != null) {
8410                        intents[intents.length-1] = rec.key.requestIntent;
8411                        rec.key.allIntents = intents;
8412                        rec.key.allResolvedTypes = resolvedTypes;
8413                    } else {
8414                        rec.key.allIntents = null;
8415                        rec.key.allResolvedTypes = null;
8416                    }
8417                }
8418                return rec;
8419            }
8420            makeIntentSenderCanceledLocked(rec);
8421            mIntentSenderRecords.remove(key);
8422        }
8423        if (noCreate) {
8424            return rec;
8425        }
8426        rec = new PendingIntentRecord(this, key, callingUid);
8427        mIntentSenderRecords.put(key, rec.ref);
8428        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8429            if (activity.pendingResults == null) {
8430                activity.pendingResults
8431                        = new HashSet<WeakReference<PendingIntentRecord>>();
8432            }
8433            activity.pendingResults.add(rec.ref);
8434        }
8435        return rec;
8436    }
8437
8438    @Override
8439    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
8440            Intent intent, String resolvedType,
8441            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
8442        if (target instanceof PendingIntentRecord) {
8443            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
8444                    whitelistToken, finishedReceiver, requiredPermission, options);
8445        } else {
8446            if (intent == null) {
8447                // Weird case: someone has given us their own custom IIntentSender, and now
8448                // they have someone else trying to send to it but of course this isn't
8449                // really a PendingIntent, so there is no base Intent, and the caller isn't
8450                // supplying an Intent... but we never want to dispatch a null Intent to
8451                // a receiver, so um...  let's make something up.
8452                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
8453                intent = new Intent(Intent.ACTION_MAIN);
8454            }
8455            try {
8456                target.send(code, intent, resolvedType, whitelistToken, null,
8457                        requiredPermission, options);
8458            } catch (RemoteException e) {
8459            }
8460            // Platform code can rely on getting a result back when the send is done, but if
8461            // this intent sender is from outside of the system we can't rely on it doing that.
8462            // So instead we don't give it the result receiver, and instead just directly
8463            // report the finish immediately.
8464            if (finishedReceiver != null) {
8465                try {
8466                    finishedReceiver.performReceive(intent, 0,
8467                            null, null, false, false, UserHandle.getCallingUserId());
8468                } catch (RemoteException e) {
8469                }
8470            }
8471            return 0;
8472        }
8473    }
8474
8475    @Override
8476    public void cancelIntentSender(IIntentSender sender) {
8477        if (!(sender instanceof PendingIntentRecord)) {
8478            return;
8479        }
8480        synchronized(this) {
8481            PendingIntentRecord rec = (PendingIntentRecord)sender;
8482            try {
8483                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
8484                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
8485                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
8486                    String msg = "Permission Denial: cancelIntentSender() from pid="
8487                        + Binder.getCallingPid()
8488                        + ", uid=" + Binder.getCallingUid()
8489                        + " is not allowed to cancel package "
8490                        + rec.key.packageName;
8491                    Slog.w(TAG, msg);
8492                    throw new SecurityException(msg);
8493                }
8494            } catch (RemoteException e) {
8495                throw new SecurityException(e);
8496            }
8497            cancelIntentSenderLocked(rec, true);
8498        }
8499    }
8500
8501    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
8502        makeIntentSenderCanceledLocked(rec);
8503        mIntentSenderRecords.remove(rec.key);
8504        if (cleanActivity && rec.key.activity != null) {
8505            rec.key.activity.pendingResults.remove(rec.ref);
8506        }
8507    }
8508
8509    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
8510        rec.canceled = true;
8511        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
8512        if (callbacks != null) {
8513            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
8514        }
8515    }
8516
8517    @Override
8518    public String getPackageForIntentSender(IIntentSender pendingResult) {
8519        if (!(pendingResult instanceof PendingIntentRecord)) {
8520            return null;
8521        }
8522        try {
8523            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8524            return res.key.packageName;
8525        } catch (ClassCastException e) {
8526        }
8527        return null;
8528    }
8529
8530    @Override
8531    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
8532        if (!(sender instanceof PendingIntentRecord)) {
8533            return;
8534        }
8535        boolean isCancelled;
8536        synchronized(this) {
8537            PendingIntentRecord pendingIntent = (PendingIntentRecord) sender;
8538            isCancelled = pendingIntent.canceled;
8539            if (!isCancelled) {
8540                pendingIntent.registerCancelListenerLocked(receiver);
8541            }
8542        }
8543        if (isCancelled) {
8544            try {
8545                receiver.send(Activity.RESULT_CANCELED, null);
8546            } catch (RemoteException e) {
8547            }
8548        }
8549    }
8550
8551    @Override
8552    public void unregisterIntentSenderCancelListener(IIntentSender sender,
8553            IResultReceiver receiver) {
8554        if (!(sender instanceof PendingIntentRecord)) {
8555            return;
8556        }
8557        synchronized(this) {
8558            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
8559        }
8560    }
8561
8562    @Override
8563    public int getUidForIntentSender(IIntentSender sender) {
8564        if (sender instanceof PendingIntentRecord) {
8565            try {
8566                PendingIntentRecord res = (PendingIntentRecord)sender;
8567                return res.uid;
8568            } catch (ClassCastException e) {
8569            }
8570        }
8571        return -1;
8572    }
8573
8574    @Override
8575    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
8576        if (!(pendingResult instanceof PendingIntentRecord)) {
8577            return false;
8578        }
8579        try {
8580            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8581            if (res.key.allIntents == null) {
8582                return false;
8583            }
8584            for (int i=0; i<res.key.allIntents.length; i++) {
8585                Intent intent = res.key.allIntents[i];
8586                if (intent.getPackage() != null && intent.getComponent() != null) {
8587                    return false;
8588                }
8589            }
8590            return true;
8591        } catch (ClassCastException e) {
8592        }
8593        return false;
8594    }
8595
8596    @Override
8597    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
8598        if (!(pendingResult instanceof PendingIntentRecord)) {
8599            return false;
8600        }
8601        try {
8602            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8603            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
8604                return true;
8605            }
8606            return false;
8607        } catch (ClassCastException e) {
8608        }
8609        return false;
8610    }
8611
8612    @Override
8613    public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
8614        if (pendingResult instanceof PendingIntentRecord) {
8615            final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
8616            return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
8617        }
8618        return false;
8619    }
8620
8621    @Override
8622    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
8623        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
8624                "getIntentForIntentSender()");
8625        if (!(pendingResult instanceof PendingIntentRecord)) {
8626            return null;
8627        }
8628        try {
8629            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8630            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
8631        } catch (ClassCastException e) {
8632        }
8633        return null;
8634    }
8635
8636    @Override
8637    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
8638        if (!(pendingResult instanceof PendingIntentRecord)) {
8639            return null;
8640        }
8641        try {
8642            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8643            synchronized (this) {
8644                return getTagForIntentSenderLocked(res, prefix);
8645            }
8646        } catch (ClassCastException e) {
8647        }
8648        return null;
8649    }
8650
8651    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
8652        final Intent intent = res.key.requestIntent;
8653        if (intent != null) {
8654            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
8655                    || res.lastTagPrefix.equals(prefix))) {
8656                return res.lastTag;
8657            }
8658            res.lastTagPrefix = prefix;
8659            final StringBuilder sb = new StringBuilder(128);
8660            if (prefix != null) {
8661                sb.append(prefix);
8662            }
8663            if (intent.getAction() != null) {
8664                sb.append(intent.getAction());
8665            } else if (intent.getComponent() != null) {
8666                intent.getComponent().appendShortString(sb);
8667            } else {
8668                sb.append("?");
8669            }
8670            return res.lastTag = sb.toString();
8671        }
8672        return null;
8673    }
8674
8675    @Override
8676    public void setProcessLimit(int max) {
8677        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8678                "setProcessLimit()");
8679        synchronized (this) {
8680            mConstants.setOverrideMaxCachedProcesses(max);
8681        }
8682        trimApplications();
8683    }
8684
8685    @Override
8686    public int getProcessLimit() {
8687        synchronized (this) {
8688            return mConstants.getOverrideMaxCachedProcesses();
8689        }
8690    }
8691
8692    void importanceTokenDied(ImportanceToken token) {
8693        synchronized (ActivityManagerService.this) {
8694            synchronized (mPidsSelfLocked) {
8695                ImportanceToken cur
8696                    = mImportantProcesses.get(token.pid);
8697                if (cur != token) {
8698                    return;
8699                }
8700                mImportantProcesses.remove(token.pid);
8701                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
8702                if (pr == null) {
8703                    return;
8704                }
8705                pr.forcingToImportant = null;
8706                updateProcessForegroundLocked(pr, false, false);
8707            }
8708            updateOomAdjLocked();
8709        }
8710    }
8711
8712    @Override
8713    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8714        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8715                "setProcessImportant()");
8716        synchronized(this) {
8717            boolean changed = false;
8718
8719            synchronized (mPidsSelfLocked) {
8720                ProcessRecord pr = mPidsSelfLocked.get(pid);
8721                if (pr == null && isForeground) {
8722                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8723                    return;
8724                }
8725                ImportanceToken oldToken = mImportantProcesses.get(pid);
8726                if (oldToken != null) {
8727                    oldToken.token.unlinkToDeath(oldToken, 0);
8728                    mImportantProcesses.remove(pid);
8729                    if (pr != null) {
8730                        pr.forcingToImportant = null;
8731                    }
8732                    changed = true;
8733                }
8734                if (isForeground && token != null) {
8735                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8736                        @Override
8737                        public void binderDied() {
8738                            importanceTokenDied(this);
8739                        }
8740                    };
8741                    try {
8742                        token.linkToDeath(newToken, 0);
8743                        mImportantProcesses.put(pid, newToken);
8744                        pr.forcingToImportant = newToken;
8745                        changed = true;
8746                    } catch (RemoteException e) {
8747                        // If the process died while doing this, we will later
8748                        // do the cleanup with the process death link.
8749                    }
8750                }
8751            }
8752
8753            if (changed) {
8754                updateOomAdjLocked();
8755            }
8756        }
8757    }
8758
8759    @Override
8760    public boolean isAppForeground(int uid) {
8761        synchronized (this) {
8762            UidRecord uidRec = mActiveUids.get(uid);
8763            if (uidRec == null || uidRec.idle) {
8764                return false;
8765            }
8766            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8767        }
8768    }
8769
8770    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8771    // be guarded by permission checking.
8772    int getUidState(int uid) {
8773        synchronized (this) {
8774            return getUidStateLocked(uid);
8775        }
8776    }
8777
8778    int getUidStateLocked(int uid) {
8779        UidRecord uidRec = mActiveUids.get(uid);
8780        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8781    }
8782
8783    @Override
8784    public boolean isInMultiWindowMode(IBinder token) {
8785        final long origId = Binder.clearCallingIdentity();
8786        try {
8787            synchronized(this) {
8788                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8789                if (r == null) {
8790                    return false;
8791                }
8792                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8793                return r.inMultiWindowMode();
8794            }
8795        } finally {
8796            Binder.restoreCallingIdentity(origId);
8797        }
8798    }
8799
8800    @Override
8801    public boolean isInPictureInPictureMode(IBinder token) {
8802        final long origId = Binder.clearCallingIdentity();
8803        try {
8804            synchronized(this) {
8805                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8806            }
8807        } finally {
8808            Binder.restoreCallingIdentity(origId);
8809        }
8810    }
8811
8812    private boolean isInPictureInPictureMode(ActivityRecord r) {
8813        if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8814                || r.getStack().isInStackLocked(r) == null) {
8815            return false;
8816        }
8817
8818        // If we are animating to fullscreen then we have already dispatched the PIP mode
8819        // changed, so we should reflect that check here as well.
8820        final PinnedActivityStack stack = r.getStack();
8821        final PinnedStackWindowController windowController = stack.getWindowContainerController();
8822        return !windowController.isAnimatingBoundsToFullscreen();
8823    }
8824
8825    @Override
8826    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8827        final long origId = Binder.clearCallingIdentity();
8828        try {
8829            synchronized(this) {
8830                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8831                        "enterPictureInPictureMode", token, params);
8832
8833                // If the activity is already in picture in picture mode, then just return early
8834                if (isInPictureInPictureMode(r)) {
8835                    return true;
8836                }
8837
8838                // Activity supports picture-in-picture, now check that we can enter PiP at this
8839                // point, if it is
8840                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8841                        false /* beforeStopping */)) {
8842                    return false;
8843                }
8844
8845                final Runnable enterPipRunnable = () -> {
8846                    // Only update the saved args from the args that are set
8847                    r.pictureInPictureArgs.copyOnlySet(params);
8848                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8849                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8850                    // Adjust the source bounds by the insets for the transition down
8851                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8852                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8853                            "enterPictureInPictureMode");
8854                    final PinnedActivityStack stack = r.getStack();
8855                    stack.setPictureInPictureAspectRatio(aspectRatio);
8856                    stack.setPictureInPictureActions(actions);
8857                    MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
8858                            r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
8859                    logPictureInPictureArgs(params);
8860                };
8861
8862                if (isKeyguardLocked()) {
8863                    // If the keyguard is showing or occluded, then try and dismiss it before
8864                    // entering picture-in-picture (this will prompt the user to authenticate if the
8865                    // device is currently locked).
8866                    try {
8867                        dismissKeyguard(token, new KeyguardDismissCallback() {
8868                            @Override
8869                            public void onDismissSucceeded() throws RemoteException {
8870                                mHandler.post(enterPipRunnable);
8871                            }
8872                        }, null /* message */);
8873                    } catch (RemoteException e) {
8874                        // Local call
8875                    }
8876                } else {
8877                    // Enter picture in picture immediately otherwise
8878                    enterPipRunnable.run();
8879                }
8880                return true;
8881            }
8882        } finally {
8883            Binder.restoreCallingIdentity(origId);
8884        }
8885    }
8886
8887    @Override
8888    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8889        final long origId = Binder.clearCallingIdentity();
8890        try {
8891            synchronized(this) {
8892                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8893                        "setPictureInPictureParams", token, params);
8894
8895                // Only update the saved args from the args that are set
8896                r.pictureInPictureArgs.copyOnlySet(params);
8897                if (r.inPinnedWindowingMode()) {
8898                    // If the activity is already in picture-in-picture, update the pinned stack now
8899                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8900                    // be used the next time the activity enters PiP
8901                    final PinnedActivityStack stack = r.getStack();
8902                    if (!stack.isAnimatingBoundsToFullscreen()) {
8903                        stack.setPictureInPictureAspectRatio(
8904                                r.pictureInPictureArgs.getAspectRatio());
8905                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8906                    }
8907                }
8908                logPictureInPictureArgs(params);
8909            }
8910        } finally {
8911            Binder.restoreCallingIdentity(origId);
8912        }
8913    }
8914
8915    @Override
8916    public int getMaxNumPictureInPictureActions(IBinder token) {
8917        // Currently, this is a static constant, but later, we may change this to be dependent on
8918        // the context of the activity
8919        return 3;
8920    }
8921
8922    private void logPictureInPictureArgs(PictureInPictureParams params) {
8923        if (params.hasSetActions()) {
8924            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8925                    params.getActions().size());
8926        }
8927        if (params.hasSetAspectRatio()) {
8928            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8929            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8930            MetricsLogger.action(lm);
8931        }
8932    }
8933
8934    /**
8935     * Checks the state of the system and the activity associated with the given {@param token} to
8936     * verify that picture-in-picture is supported for that activity.
8937     *
8938     * @return the activity record for the given {@param token} if all the checks pass.
8939     */
8940    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8941            IBinder token, PictureInPictureParams params) {
8942        if (!mSupportsPictureInPicture) {
8943            throw new IllegalStateException(caller
8944                    + ": Device doesn't support picture-in-picture mode.");
8945        }
8946
8947        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8948        if (r == null) {
8949            throw new IllegalStateException(caller
8950                    + ": Can't find activity for token=" + token);
8951        }
8952
8953        if (!r.supportsPictureInPicture()) {
8954            throw new IllegalStateException(caller
8955                    + ": Current activity does not support picture-in-picture.");
8956        }
8957
8958        if (params.hasSetAspectRatio()
8959                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8960                        params.getAspectRatio())) {
8961            final float minAspectRatio = mContext.getResources().getFloat(
8962                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8963            final float maxAspectRatio = mContext.getResources().getFloat(
8964                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8965            throw new IllegalArgumentException(String.format(caller
8966                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8967                            minAspectRatio, maxAspectRatio));
8968        }
8969
8970        // Truncate the number of actions if necessary
8971        params.truncateActions(getMaxNumPictureInPictureActions(token));
8972
8973        return r;
8974    }
8975
8976    // =========================================================
8977    // PROCESS INFO
8978    // =========================================================
8979
8980    static class ProcessInfoService extends IProcessInfoService.Stub {
8981        final ActivityManagerService mActivityManagerService;
8982        ProcessInfoService(ActivityManagerService activityManagerService) {
8983            mActivityManagerService = activityManagerService;
8984        }
8985
8986        @Override
8987        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8988            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8989                    /*in*/ pids, /*out*/ states, null);
8990        }
8991
8992        @Override
8993        public void getProcessStatesAndOomScoresFromPids(
8994                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8995            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8996                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8997        }
8998    }
8999
9000    /**
9001     * For each PID in the given input array, write the current process state
9002     * for that process into the states array, or -1 to indicate that no
9003     * process with the given PID exists. If scores array is provided, write
9004     * the oom score for the process into the scores array, with INVALID_ADJ
9005     * indicating the PID doesn't exist.
9006     */
9007    public void getProcessStatesAndOomScoresForPIDs(
9008            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
9009        if (scores != null) {
9010            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
9011                    "getProcessStatesAndOomScoresForPIDs()");
9012        }
9013
9014        if (pids == null) {
9015            throw new NullPointerException("pids");
9016        } else if (states == null) {
9017            throw new NullPointerException("states");
9018        } else if (pids.length != states.length) {
9019            throw new IllegalArgumentException("pids and states arrays have different lengths!");
9020        } else if (scores != null && pids.length != scores.length) {
9021            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
9022        }
9023
9024        synchronized (mPidsSelfLocked) {
9025            for (int i = 0; i < pids.length; i++) {
9026                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
9027                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
9028                        pr.curProcState;
9029                if (scores != null) {
9030                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
9031                }
9032            }
9033        }
9034    }
9035
9036    // =========================================================
9037    // PERMISSIONS
9038    // =========================================================
9039
9040    static class PermissionController extends IPermissionController.Stub {
9041        ActivityManagerService mActivityManagerService;
9042        PermissionController(ActivityManagerService activityManagerService) {
9043            mActivityManagerService = activityManagerService;
9044        }
9045
9046        @Override
9047        public boolean checkPermission(String permission, int pid, int uid) {
9048            return mActivityManagerService.checkPermission(permission, pid,
9049                    uid) == PackageManager.PERMISSION_GRANTED;
9050        }
9051
9052        @Override
9053        public int noteOp(String op, int uid, String packageName) {
9054            return mActivityManagerService.mAppOpsService
9055                    .noteOperation(AppOpsManager.strOpToOp(op), uid, packageName);
9056        }
9057
9058        @Override
9059        public String[] getPackagesForUid(int uid) {
9060            return mActivityManagerService.mContext.getPackageManager()
9061                    .getPackagesForUid(uid);
9062        }
9063
9064        @Override
9065        public boolean isRuntimePermission(String permission) {
9066            try {
9067                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
9068                        .getPermissionInfo(permission, 0);
9069                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
9070                        == PermissionInfo.PROTECTION_DANGEROUS;
9071            } catch (NameNotFoundException nnfe) {
9072                Slog.e(TAG, "No such permission: "+ permission, nnfe);
9073            }
9074            return false;
9075        }
9076
9077        @Override
9078        public int getPackageUid(String packageName, int flags) {
9079            try {
9080                return mActivityManagerService.mContext.getPackageManager()
9081                        .getPackageUid(packageName, flags);
9082            } catch (NameNotFoundException nnfe) {
9083                return -1;
9084            }
9085        }
9086    }
9087
9088    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
9089        @Override
9090        public int checkComponentPermission(String permission, int pid, int uid,
9091                int owningUid, boolean exported) {
9092            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
9093                    owningUid, exported);
9094        }
9095
9096        @Override
9097        public Object getAMSLock() {
9098            return ActivityManagerService.this;
9099        }
9100    }
9101
9102    int checkComponentPermission(String permission, int pid, int uid,
9103            int owningUid, boolean exported) {
9104        if (pid == MY_PID) {
9105            return PackageManager.PERMISSION_GRANTED;
9106        }
9107        return ActivityManager.checkComponentPermission(permission, uid,
9108                owningUid, exported);
9109    }
9110
9111    /**
9112     * As the only public entry point for permissions checking, this method
9113     * can enforce the semantic that requesting a check on a null global
9114     * permission is automatically denied.  (Internally a null permission
9115     * string is used when calling {@link #checkComponentPermission} in cases
9116     * when only uid-based security is needed.)
9117     *
9118     * This can be called with or without the global lock held.
9119     */
9120    @Override
9121    public int checkPermission(String permission, int pid, int uid) {
9122        if (permission == null) {
9123            return PackageManager.PERMISSION_DENIED;
9124        }
9125        return checkComponentPermission(permission, pid, uid, -1, true);
9126    }
9127
9128    @Override
9129    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
9130        if (permission == null) {
9131            return PackageManager.PERMISSION_DENIED;
9132        }
9133
9134        // We might be performing an operation on behalf of an indirect binder
9135        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
9136        // client identity accordingly before proceeding.
9137        Identity tlsIdentity = sCallerIdentity.get();
9138        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9139            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
9140                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
9141            uid = tlsIdentity.uid;
9142            pid = tlsIdentity.pid;
9143        }
9144
9145        return checkComponentPermission(permission, pid, uid, -1, true);
9146    }
9147
9148    /**
9149     * Binder IPC calls go through the public entry point.
9150     * This can be called with or without the global lock held.
9151     */
9152    int checkCallingPermission(String permission) {
9153        return checkPermission(permission,
9154                Binder.getCallingPid(),
9155                UserHandle.getAppId(Binder.getCallingUid()));
9156    }
9157
9158    /**
9159     * This can be called with or without the global lock held.
9160     */
9161    void enforceCallingPermission(String permission, String func) {
9162        if (checkCallingPermission(permission)
9163                == PackageManager.PERMISSION_GRANTED) {
9164            return;
9165        }
9166
9167        String msg = "Permission Denial: " + func + " from pid="
9168                + Binder.getCallingPid()
9169                + ", uid=" + Binder.getCallingUid()
9170                + " requires " + permission;
9171        Slog.w(TAG, msg);
9172        throw new SecurityException(msg);
9173    }
9174
9175    /**
9176     * This can be called with or without the global lock held.
9177     */
9178    void enforcePermission(String permission, int pid, int uid, String func) {
9179        if (checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED) {
9180            return;
9181        }
9182
9183        String msg = "Permission Denial: " + func + " from pid=" + pid + ", uid=" + uid
9184                + " requires " + permission;
9185        Slog.w(TAG, msg);
9186        throw new SecurityException(msg);
9187    }
9188
9189    /**
9190     * This can be called with or without the global lock held.
9191     */
9192    void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
9193        if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
9194            enforceCallingPermission(permission, func);
9195        }
9196    }
9197
9198    /**
9199     * Determine if UID is holding permissions required to access {@link Uri} in
9200     * the given {@link ProviderInfo}. Final permission checking is always done
9201     * in {@link ContentProvider}.
9202     */
9203    private final boolean checkHoldingPermissionsLocked(
9204            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
9205        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9206                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
9207        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
9208            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
9209                    != PERMISSION_GRANTED) {
9210                return false;
9211            }
9212        }
9213        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
9214    }
9215
9216    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
9217            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
9218        if (pi.applicationInfo.uid == uid) {
9219            return true;
9220        } else if (!pi.exported) {
9221            return false;
9222        }
9223
9224        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
9225        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
9226        try {
9227            // check if target holds top-level <provider> permissions
9228            if (!readMet && pi.readPermission != null && considerUidPermissions
9229                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
9230                readMet = true;
9231            }
9232            if (!writeMet && pi.writePermission != null && considerUidPermissions
9233                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
9234                writeMet = true;
9235            }
9236
9237            // track if unprotected read/write is allowed; any denied
9238            // <path-permission> below removes this ability
9239            boolean allowDefaultRead = pi.readPermission == null;
9240            boolean allowDefaultWrite = pi.writePermission == null;
9241
9242            // check if target holds any <path-permission> that match uri
9243            final PathPermission[] pps = pi.pathPermissions;
9244            if (pps != null) {
9245                final String path = grantUri.uri.getPath();
9246                int i = pps.length;
9247                while (i > 0 && (!readMet || !writeMet)) {
9248                    i--;
9249                    PathPermission pp = pps[i];
9250                    if (pp.match(path)) {
9251                        if (!readMet) {
9252                            final String pprperm = pp.getReadPermission();
9253                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9254                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
9255                                    + ": match=" + pp.match(path)
9256                                    + " check=" + pm.checkUidPermission(pprperm, uid));
9257                            if (pprperm != null) {
9258                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
9259                                        == PERMISSION_GRANTED) {
9260                                    readMet = true;
9261                                } else {
9262                                    allowDefaultRead = false;
9263                                }
9264                            }
9265                        }
9266                        if (!writeMet) {
9267                            final String ppwperm = pp.getWritePermission();
9268                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9269                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
9270                                    + ": match=" + pp.match(path)
9271                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
9272                            if (ppwperm != null) {
9273                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
9274                                        == PERMISSION_GRANTED) {
9275                                    writeMet = true;
9276                                } else {
9277                                    allowDefaultWrite = false;
9278                                }
9279                            }
9280                        }
9281                    }
9282                }
9283            }
9284
9285            // grant unprotected <provider> read/write, if not blocked by
9286            // <path-permission> above
9287            if (allowDefaultRead) readMet = true;
9288            if (allowDefaultWrite) writeMet = true;
9289
9290        } catch (RemoteException e) {
9291            return false;
9292        }
9293
9294        return readMet && writeMet;
9295    }
9296
9297    public boolean isAppStartModeDisabled(int uid, String packageName) {
9298        synchronized (this) {
9299            return getAppStartModeLocked(uid, packageName, 0, -1, false, true, false)
9300                    == ActivityManager.APP_START_MODE_DISABLED;
9301        }
9302    }
9303
9304    // Unified app-op and target sdk check
9305    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9306        // Apps that target O+ are always subject to background check
9307        if (packageTargetSdk >= Build.VERSION_CODES.O) {
9308            if (DEBUG_BACKGROUND_CHECK) {
9309                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
9310            }
9311            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9312        }
9313        // ...and legacy apps get an AppOp check
9314        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
9315                uid, packageName);
9316        if (DEBUG_BACKGROUND_CHECK) {
9317            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
9318        }
9319        switch (appop) {
9320            case AppOpsManager.MODE_ALLOWED:
9321                // If force-background-check is enabled, restrict all apps that aren't whitelisted.
9322                if (mForceBackgroundCheck &&
9323                        !UserHandle.isCore(uid) &&
9324                        !isOnDeviceIdleWhitelistLocked(uid, /*allowExceptIdleToo=*/ true)) {
9325                    if (DEBUG_BACKGROUND_CHECK) {
9326                        Slog.i(TAG, "Force background check: " +
9327                                uid + "/" + packageName + " restricted");
9328                    }
9329                    return ActivityManager.APP_START_MODE_DELAYED;
9330                }
9331                return ActivityManager.APP_START_MODE_NORMAL;
9332            case AppOpsManager.MODE_IGNORED:
9333                return ActivityManager.APP_START_MODE_DELAYED;
9334            default:
9335                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9336        }
9337    }
9338
9339    // Service launch is available to apps with run-in-background exemptions but
9340    // some other background operations are not.  If we're doing a check
9341    // of service-launch policy, allow those callers to proceed unrestricted.
9342    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9343        // Persistent app?
9344        if (mPackageManagerInt.isPackagePersistent(packageName)) {
9345            if (DEBUG_BACKGROUND_CHECK) {
9346                Slog.i(TAG, "App " + uid + "/" + packageName
9347                        + " is persistent; not restricted in background");
9348            }
9349            return ActivityManager.APP_START_MODE_NORMAL;
9350        }
9351
9352        // Non-persistent but background whitelisted?
9353        if (uidOnBackgroundWhitelist(uid)) {
9354            if (DEBUG_BACKGROUND_CHECK) {
9355                Slog.i(TAG, "App " + uid + "/" + packageName
9356                        + " on background whitelist; not restricted in background");
9357            }
9358            return ActivityManager.APP_START_MODE_NORMAL;
9359        }
9360
9361        // Is this app on the battery whitelist?
9362        if (isOnDeviceIdleWhitelistLocked(uid, /*allowExceptIdleToo=*/ false)) {
9363            if (DEBUG_BACKGROUND_CHECK) {
9364                Slog.i(TAG, "App " + uid + "/" + packageName
9365                        + " on idle whitelist; not restricted in background");
9366            }
9367            return ActivityManager.APP_START_MODE_NORMAL;
9368        }
9369
9370        // None of the service-policy criteria apply, so we apply the common criteria
9371        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
9372    }
9373
9374    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
9375            int callingPid, boolean alwaysRestrict, boolean disabledOnly, boolean forcedStandby) {
9376        UidRecord uidRec = mActiveUids.get(uid);
9377        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
9378                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
9379                + (uidRec != null ? uidRec.idle : false));
9380        if (uidRec == null || alwaysRestrict || forcedStandby || uidRec.idle) {
9381            boolean ephemeral;
9382            if (uidRec == null) {
9383                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
9384                        UserHandle.getUserId(uid), packageName);
9385            } else {
9386                ephemeral = uidRec.ephemeral;
9387            }
9388
9389            if (ephemeral) {
9390                // We are hard-core about ephemeral apps not running in the background.
9391                return ActivityManager.APP_START_MODE_DISABLED;
9392            } else {
9393                if (disabledOnly) {
9394                    // The caller is only interested in whether app starts are completely
9395                    // disabled for the given package (that is, it is an instant app).  So
9396                    // we don't need to go further, which is all just seeing if we should
9397                    // apply a "delayed" mode for a regular app.
9398                    return ActivityManager.APP_START_MODE_NORMAL;
9399                }
9400                final int startMode = (alwaysRestrict)
9401                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
9402                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
9403                                packageTargetSdk);
9404                if (DEBUG_BACKGROUND_CHECK) {
9405                    Slog.d(TAG, "checkAllowBackground: uid=" + uid
9406                            + " pkg=" + packageName + " startMode=" + startMode
9407                            + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid, false)
9408                            + " onwhitelist(ei)=" + isOnDeviceIdleWhitelistLocked(uid, true));
9409                }
9410                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
9411                    // This is an old app that has been forced into a "compatible as possible"
9412                    // mode of background check.  To increase compatibility, we will allow other
9413                    // foreground apps to cause its services to start.
9414                    if (callingPid >= 0) {
9415                        ProcessRecord proc;
9416                        synchronized (mPidsSelfLocked) {
9417                            proc = mPidsSelfLocked.get(callingPid);
9418                        }
9419                        if (proc != null &&
9420                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
9421                            // Whoever is instigating this is in the foreground, so we will allow it
9422                            // to go through.
9423                            return ActivityManager.APP_START_MODE_NORMAL;
9424                        }
9425                    }
9426                }
9427                return startMode;
9428            }
9429        }
9430        return ActivityManager.APP_START_MODE_NORMAL;
9431    }
9432
9433    /**
9434     * @return whether a UID is in the system, user or temp doze whitelist.
9435     */
9436    boolean isOnDeviceIdleWhitelistLocked(int uid, boolean allowExceptIdleToo) {
9437        final int appId = UserHandle.getAppId(uid);
9438
9439        final int[] whitelist = allowExceptIdleToo
9440                ? mDeviceIdleExceptIdleWhitelist
9441                : mDeviceIdleWhitelist;
9442
9443        return Arrays.binarySearch(whitelist, appId) >= 0
9444                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
9445                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
9446    }
9447
9448    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
9449        ProviderInfo pi = null;
9450        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
9451        if (cpr != null) {
9452            pi = cpr.info;
9453        } else {
9454            try {
9455                pi = AppGlobals.getPackageManager().resolveContentProvider(
9456                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
9457                        userHandle);
9458            } catch (RemoteException ex) {
9459            }
9460        }
9461        return pi;
9462    }
9463
9464    void grantEphemeralAccessLocked(int userId, Intent intent,
9465            int targetAppId, int ephemeralAppId) {
9466        getPackageManagerInternalLocked().
9467                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
9468    }
9469
9470    @GuardedBy("this")
9471    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
9472        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9473        if (targetUris != null) {
9474            return targetUris.get(grantUri);
9475        }
9476        return null;
9477    }
9478
9479    @GuardedBy("this")
9480    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
9481            String targetPkg, int targetUid, GrantUri grantUri) {
9482        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9483        if (targetUris == null) {
9484            targetUris = Maps.newArrayMap();
9485            mGrantedUriPermissions.put(targetUid, targetUris);
9486        }
9487
9488        UriPermission perm = targetUris.get(grantUri);
9489        if (perm == null) {
9490            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
9491            targetUris.put(grantUri, perm);
9492        }
9493
9494        return perm;
9495    }
9496
9497    @GuardedBy("this")
9498    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
9499            final int modeFlags) {
9500        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
9501        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
9502                : UriPermission.STRENGTH_OWNED;
9503
9504        // Root gets to do everything.
9505        if (uid == 0) {
9506            return true;
9507        }
9508
9509        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9510        if (perms == null) return false;
9511
9512        // First look for exact match
9513        final UriPermission exactPerm = perms.get(grantUri);
9514        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
9515            return true;
9516        }
9517
9518        // No exact match, look for prefixes
9519        final int N = perms.size();
9520        for (int i = 0; i < N; i++) {
9521            final UriPermission perm = perms.valueAt(i);
9522            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
9523                    && perm.getStrength(modeFlags) >= minStrength) {
9524                return true;
9525            }
9526        }
9527
9528        return false;
9529    }
9530
9531    /**
9532     * @param uri This uri must NOT contain an embedded userId.
9533     * @param userId The userId in which the uri is to be resolved.
9534     */
9535    @Override
9536    public int checkUriPermission(Uri uri, int pid, int uid,
9537            final int modeFlags, int userId, IBinder callerToken) {
9538        enforceNotIsolatedCaller("checkUriPermission");
9539
9540        // Another redirected-binder-call permissions check as in
9541        // {@link checkPermissionWithToken}.
9542        Identity tlsIdentity = sCallerIdentity.get();
9543        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9544            uid = tlsIdentity.uid;
9545            pid = tlsIdentity.pid;
9546        }
9547
9548        // Our own process gets to do everything.
9549        if (pid == MY_PID) {
9550            return PackageManager.PERMISSION_GRANTED;
9551        }
9552        synchronized (this) {
9553            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
9554                    ? PackageManager.PERMISSION_GRANTED
9555                    : PackageManager.PERMISSION_DENIED;
9556        }
9557    }
9558
9559    /**
9560     * Check if the targetPkg can be granted permission to access uri by
9561     * the callingUid using the given modeFlags.  Throws a security exception
9562     * if callingUid is not allowed to do this.  Returns the uid of the target
9563     * if the URI permission grant should be performed; returns -1 if it is not
9564     * needed (for example targetPkg already has permission to access the URI).
9565     * If you already know the uid of the target, you can supply it in
9566     * lastTargetUid else set that to -1.
9567     */
9568    @GuardedBy("this")
9569    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9570            final int modeFlags, int lastTargetUid) {
9571        if (!Intent.isAccessUriMode(modeFlags)) {
9572            return -1;
9573        }
9574
9575        if (targetPkg != null) {
9576            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9577                    "Checking grant " + targetPkg + " permission to " + grantUri);
9578        }
9579
9580        final IPackageManager pm = AppGlobals.getPackageManager();
9581
9582        // If this is not a content: uri, we can't do anything with it.
9583        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
9584            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9585                    "Can't grant URI permission for non-content URI: " + grantUri);
9586            return -1;
9587        }
9588
9589        // Bail early if system is trying to hand out permissions directly; it
9590        // must always grant permissions on behalf of someone explicit.
9591        final int callingAppId = UserHandle.getAppId(callingUid);
9592        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
9593            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
9594                // Exempted authority for
9595                // 1. cropping user photos and sharing a generated license html
9596                //    file in Settings app
9597                // 2. sharing a generated license html file in TvSettings app
9598            } else {
9599                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
9600                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
9601                return -1;
9602            }
9603        }
9604
9605        final String authority = grantUri.uri.getAuthority();
9606        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9607                MATCH_DEBUG_TRIAGED_MISSING);
9608        if (pi == null) {
9609            Slog.w(TAG, "No content provider found for permission check: " +
9610                    grantUri.uri.toSafeString());
9611            return -1;
9612        }
9613
9614        int targetUid = lastTargetUid;
9615        if (targetUid < 0 && targetPkg != null) {
9616            try {
9617                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9618                        UserHandle.getUserId(callingUid));
9619                if (targetUid < 0) {
9620                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9621                            "Can't grant URI permission no uid for: " + targetPkg);
9622                    return -1;
9623                }
9624            } catch (RemoteException ex) {
9625                return -1;
9626            }
9627        }
9628
9629        // If we're extending a persistable grant, then we always need to create
9630        // the grant data structure so that take/release APIs work
9631        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
9632            return targetUid;
9633        }
9634
9635        if (targetUid >= 0) {
9636            // First...  does the target actually need this permission?
9637            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
9638                // No need to grant the target this permission.
9639                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9640                        "Target " + targetPkg + " already has full permission to " + grantUri);
9641                return -1;
9642            }
9643        } else {
9644            // First...  there is no target package, so can anyone access it?
9645            boolean allowed = pi.exported;
9646            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9647                if (pi.readPermission != null) {
9648                    allowed = false;
9649                }
9650            }
9651            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9652                if (pi.writePermission != null) {
9653                    allowed = false;
9654                }
9655            }
9656            if (pi.pathPermissions != null) {
9657                final int N = pi.pathPermissions.length;
9658                for (int i=0; i<N; i++) {
9659                    if (pi.pathPermissions[i] != null
9660                            && pi.pathPermissions[i].match(grantUri.uri.getPath())) {
9661                        if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9662                            if (pi.pathPermissions[i].getReadPermission() != null) {
9663                                allowed = false;
9664                            }
9665                        }
9666                        if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9667                            if (pi.pathPermissions[i].getWritePermission() != null) {
9668                                allowed = false;
9669                            }
9670                        }
9671                        break;
9672                    }
9673                }
9674            }
9675            if (allowed) {
9676                return -1;
9677            }
9678        }
9679
9680        /* There is a special cross user grant if:
9681         * - The target is on another user.
9682         * - Apps on the current user can access the uri without any uid permissions.
9683         * In this case, we grant a uri permission, even if the ContentProvider does not normally
9684         * grant uri permissions.
9685         */
9686        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
9687                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
9688                modeFlags, false /*without considering the uid permissions*/);
9689
9690        // Second...  is the provider allowing granting of URI permissions?
9691        if (!specialCrossUserGrant) {
9692            if (!pi.grantUriPermissions) {
9693                throw new SecurityException("Provider " + pi.packageName
9694                        + "/" + pi.name
9695                        + " does not allow granting of Uri permissions (uri "
9696                        + grantUri + ")");
9697            }
9698            if (pi.uriPermissionPatterns != null) {
9699                final int N = pi.uriPermissionPatterns.length;
9700                boolean allowed = false;
9701                for (int i=0; i<N; i++) {
9702                    if (pi.uriPermissionPatterns[i] != null
9703                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
9704                        allowed = true;
9705                        break;
9706                    }
9707                }
9708                if (!allowed) {
9709                    throw new SecurityException("Provider " + pi.packageName
9710                            + "/" + pi.name
9711                            + " does not allow granting of permission to path of Uri "
9712                            + grantUri);
9713                }
9714            }
9715        }
9716
9717        // Third...  does the caller itself have permission to access
9718        // this uri?
9719        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9720            // Require they hold a strong enough Uri permission
9721            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
9722                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
9723                    throw new SecurityException(
9724                            "UID " + callingUid + " does not have permission to " + grantUri
9725                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
9726                                    + "or related APIs");
9727                } else {
9728                    throw new SecurityException(
9729                            "UID " + callingUid + " does not have permission to " + grantUri);
9730                }
9731            }
9732        }
9733        return targetUid;
9734    }
9735
9736    /**
9737     * @param uri This uri must NOT contain an embedded userId.
9738     * @param userId The userId in which the uri is to be resolved.
9739     */
9740    @Override
9741    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
9742            final int modeFlags, int userId) {
9743        enforceNotIsolatedCaller("checkGrantUriPermission");
9744        synchronized(this) {
9745            return checkGrantUriPermissionLocked(callingUid, targetPkg,
9746                    new GrantUri(userId, uri, false), modeFlags, -1);
9747        }
9748    }
9749
9750    @GuardedBy("this")
9751    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
9752            final int modeFlags, UriPermissionOwner owner) {
9753        if (!Intent.isAccessUriMode(modeFlags)) {
9754            return;
9755        }
9756
9757        // So here we are: the caller has the assumed permission
9758        // to the uri, and the target doesn't.  Let's now give this to
9759        // the target.
9760
9761        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9762                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
9763
9764        final String authority = grantUri.uri.getAuthority();
9765        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9766                MATCH_DEBUG_TRIAGED_MISSING);
9767        if (pi == null) {
9768            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
9769            return;
9770        }
9771
9772        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
9773            grantUri.prefix = true;
9774        }
9775        final UriPermission perm = findOrCreateUriPermissionLocked(
9776                pi.packageName, targetPkg, targetUid, grantUri);
9777        perm.grantModes(modeFlags, owner);
9778    }
9779
9780    @GuardedBy("this")
9781    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9782            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9783        if (targetPkg == null) {
9784            throw new NullPointerException("targetPkg");
9785        }
9786        int targetUid;
9787        final IPackageManager pm = AppGlobals.getPackageManager();
9788        try {
9789            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9790        } catch (RemoteException ex) {
9791            return;
9792        }
9793
9794        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9795                targetUid);
9796        if (targetUid < 0) {
9797            return;
9798        }
9799
9800        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9801                owner);
9802    }
9803
9804    static class NeededUriGrants extends ArrayList<GrantUri> {
9805        final String targetPkg;
9806        final int targetUid;
9807        final int flags;
9808
9809        NeededUriGrants(String targetPkg, int targetUid, int flags) {
9810            this.targetPkg = targetPkg;
9811            this.targetUid = targetUid;
9812            this.flags = flags;
9813        }
9814
9815        void writeToProto(ProtoOutputStream proto, long fieldId) {
9816            long token = proto.start(fieldId);
9817            proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
9818            proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
9819            proto.write(NeededUriGrantsProto.FLAGS, flags);
9820
9821            final int N = this.size();
9822            for (int i=0; i<N; i++) {
9823                this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
9824            }
9825            proto.end(token);
9826        }
9827    }
9828
9829    /**
9830     * Like checkGrantUriPermissionLocked, but takes an Intent.
9831     */
9832    @GuardedBy("this")
9833    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9834            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9835        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9836                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9837                + " clip=" + (intent != null ? intent.getClipData() : null)
9838                + " from " + intent + "; flags=0x"
9839                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9840
9841        if (targetPkg == null) {
9842            throw new NullPointerException("targetPkg");
9843        }
9844
9845        if (intent == null) {
9846            return null;
9847        }
9848        Uri data = intent.getData();
9849        ClipData clip = intent.getClipData();
9850        if (data == null && clip == null) {
9851            return null;
9852        }
9853        // Default userId for uris in the intent (if they don't specify it themselves)
9854        int contentUserHint = intent.getContentUserHint();
9855        if (contentUserHint == UserHandle.USER_CURRENT) {
9856            contentUserHint = UserHandle.getUserId(callingUid);
9857        }
9858        final IPackageManager pm = AppGlobals.getPackageManager();
9859        int targetUid;
9860        if (needed != null) {
9861            targetUid = needed.targetUid;
9862        } else {
9863            try {
9864                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9865                        targetUserId);
9866            } catch (RemoteException ex) {
9867                return null;
9868            }
9869            if (targetUid < 0) {
9870                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9871                        "Can't grant URI permission no uid for: " + targetPkg
9872                        + " on user " + targetUserId);
9873                return null;
9874            }
9875        }
9876        if (data != null) {
9877            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9878            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9879                    targetUid);
9880            if (targetUid > 0) {
9881                if (needed == null) {
9882                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
9883                }
9884                needed.add(grantUri);
9885            }
9886        }
9887        if (clip != null) {
9888            for (int i=0; i<clip.getItemCount(); i++) {
9889                Uri uri = clip.getItemAt(i).getUri();
9890                if (uri != null) {
9891                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9892                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9893                            targetUid);
9894                    if (targetUid > 0) {
9895                        if (needed == null) {
9896                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
9897                        }
9898                        needed.add(grantUri);
9899                    }
9900                } else {
9901                    Intent clipIntent = clip.getItemAt(i).getIntent();
9902                    if (clipIntent != null) {
9903                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9904                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9905                        if (newNeeded != null) {
9906                            needed = newNeeded;
9907                        }
9908                    }
9909                }
9910            }
9911        }
9912
9913        return needed;
9914    }
9915
9916    /**
9917     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9918     */
9919    @GuardedBy("this")
9920    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9921            UriPermissionOwner owner) {
9922        if (needed != null) {
9923            for (int i=0; i<needed.size(); i++) {
9924                GrantUri grantUri = needed.get(i);
9925                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9926                        grantUri, needed.flags, owner);
9927            }
9928        }
9929    }
9930
9931    @GuardedBy("this")
9932    void grantUriPermissionFromIntentLocked(int callingUid,
9933            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9934        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9935                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9936        if (needed == null) {
9937            return;
9938        }
9939
9940        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9941    }
9942
9943    /**
9944     * @param uri This uri must NOT contain an embedded userId.
9945     * @param userId The userId in which the uri is to be resolved.
9946     */
9947    @Override
9948    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9949            final int modeFlags, int userId) {
9950        enforceNotIsolatedCaller("grantUriPermission");
9951        GrantUri grantUri = new GrantUri(userId, uri, false);
9952        synchronized(this) {
9953            final ProcessRecord r = getRecordForAppLocked(caller);
9954            if (r == null) {
9955                throw new SecurityException("Unable to find app for caller "
9956                        + caller
9957                        + " when granting permission to uri " + grantUri);
9958            }
9959            if (targetPkg == null) {
9960                throw new IllegalArgumentException("null target");
9961            }
9962            if (grantUri == null) {
9963                throw new IllegalArgumentException("null uri");
9964            }
9965
9966            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9967                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9968                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9969                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9970
9971            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9972                    UserHandle.getUserId(r.uid));
9973        }
9974    }
9975
9976    @GuardedBy("this")
9977    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9978        if (perm.modeFlags == 0) {
9979            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9980                    perm.targetUid);
9981            if (perms != null) {
9982                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9983                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9984
9985                perms.remove(perm.uri);
9986                if (perms.isEmpty()) {
9987                    mGrantedUriPermissions.remove(perm.targetUid);
9988                }
9989            }
9990        }
9991    }
9992
9993    @GuardedBy("this")
9994    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9995            final int modeFlags) {
9996        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9997                "Revoking all granted permissions to " + grantUri);
9998
9999        final IPackageManager pm = AppGlobals.getPackageManager();
10000        final String authority = grantUri.uri.getAuthority();
10001        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
10002                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
10003        if (pi == null) {
10004            Slog.w(TAG, "No content provider found for permission revoke: "
10005                    + grantUri.toSafeString());
10006            return;
10007        }
10008
10009        // Does the caller have this permission on the URI?
10010        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
10011            // If they don't have direct access to the URI, then revoke any
10012            // ownerless URI permissions that have been granted to them.
10013            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10014            if (perms != null) {
10015                boolean persistChanged = false;
10016                for (int i = perms.size()-1; i >= 0; i--) {
10017                    final UriPermission perm = perms.valueAt(i);
10018                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
10019                        continue;
10020                    }
10021                    if (perm.uri.sourceUserId == grantUri.sourceUserId
10022                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
10023                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10024                                "Revoking non-owned " + perm.targetUid
10025                                + " permission to " + perm.uri);
10026                        persistChanged |= perm.revokeModes(
10027                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
10028                        if (perm.modeFlags == 0) {
10029                            perms.removeAt(i);
10030                        }
10031                    }
10032                }
10033                if (perms.isEmpty()) {
10034                    mGrantedUriPermissions.remove(callingUid);
10035                }
10036                if (persistChanged) {
10037                    schedulePersistUriGrants();
10038                }
10039            }
10040            return;
10041        }
10042
10043        boolean persistChanged = false;
10044
10045        // Go through all of the permissions and remove any that match.
10046        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
10047            final int targetUid = mGrantedUriPermissions.keyAt(i);
10048            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10049
10050            for (int j = perms.size()-1; j >= 0; j--) {
10051                final UriPermission perm = perms.valueAt(j);
10052                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
10053                    continue;
10054                }
10055                if (perm.uri.sourceUserId == grantUri.sourceUserId
10056                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
10057                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10058                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
10059                    persistChanged |= perm.revokeModes(
10060                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
10061                            targetPackage == null);
10062                    if (perm.modeFlags == 0) {
10063                        perms.removeAt(j);
10064                    }
10065                }
10066            }
10067
10068            if (perms.isEmpty()) {
10069                mGrantedUriPermissions.removeAt(i);
10070            }
10071        }
10072
10073        if (persistChanged) {
10074            schedulePersistUriGrants();
10075        }
10076    }
10077
10078    /**
10079     * @param uri This uri must NOT contain an embedded userId.
10080     * @param userId The userId in which the uri is to be resolved.
10081     */
10082    @Override
10083    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
10084            final int modeFlags, int userId) {
10085        enforceNotIsolatedCaller("revokeUriPermission");
10086        synchronized(this) {
10087            final ProcessRecord r = getRecordForAppLocked(caller);
10088            if (r == null) {
10089                throw new SecurityException("Unable to find app for caller "
10090                        + caller
10091                        + " when revoking permission to uri " + uri);
10092            }
10093            if (uri == null) {
10094                Slog.w(TAG, "revokeUriPermission: null uri");
10095                return;
10096            }
10097
10098            if (!Intent.isAccessUriMode(modeFlags)) {
10099                return;
10100            }
10101
10102            final String authority = uri.getAuthority();
10103            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
10104                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
10105            if (pi == null) {
10106                Slog.w(TAG, "No content provider found for permission revoke: "
10107                        + uri.toSafeString());
10108                return;
10109            }
10110
10111            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
10112                    modeFlags);
10113        }
10114    }
10115
10116    /**
10117     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
10118     * given package.
10119     *
10120     * @param packageName Package name to match, or {@code null} to apply to all
10121     *            packages.
10122     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
10123     *            to all users.
10124     * @param persistable If persistable grants should be removed.
10125     * @param targetOnly When {@code true}, only remove permissions where the app is the target,
10126     * not source.
10127     */
10128    @GuardedBy("this")
10129    private void removeUriPermissionsForPackageLocked(
10130            String packageName, int userHandle, boolean persistable, boolean targetOnly) {
10131        if (userHandle == UserHandle.USER_ALL && packageName == null) {
10132            throw new IllegalArgumentException("Must narrow by either package or user");
10133        }
10134
10135        boolean persistChanged = false;
10136
10137        int N = mGrantedUriPermissions.size();
10138        for (int i = 0; i < N; i++) {
10139            final int targetUid = mGrantedUriPermissions.keyAt(i);
10140            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10141
10142            // Only inspect grants matching user
10143            if (userHandle == UserHandle.USER_ALL
10144                    || userHandle == UserHandle.getUserId(targetUid)) {
10145                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
10146                    final UriPermission perm = it.next();
10147
10148                    // Only inspect grants matching package
10149                    if (packageName == null || (!targetOnly && perm.sourcePkg.equals(packageName))
10150                            || perm.targetPkg.equals(packageName)) {
10151                        // Hacky solution as part of fixing a security bug; ignore
10152                        // grants associated with DownloadManager so we don't have
10153                        // to immediately launch it to regrant the permissions
10154                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
10155                                && !persistable) continue;
10156
10157                        persistChanged |= perm.revokeModes(persistable
10158                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
10159
10160                        // Only remove when no modes remain; any persisted grants
10161                        // will keep this alive.
10162                        if (perm.modeFlags == 0) {
10163                            it.remove();
10164                        }
10165                    }
10166                }
10167
10168                if (perms.isEmpty()) {
10169                    mGrantedUriPermissions.remove(targetUid);
10170                    N--;
10171                    i--;
10172                }
10173            }
10174        }
10175
10176        if (persistChanged) {
10177            schedulePersistUriGrants();
10178        }
10179    }
10180
10181    @Override
10182    public IBinder newUriPermissionOwner(String name) {
10183        enforceNotIsolatedCaller("newUriPermissionOwner");
10184        synchronized(this) {
10185            UriPermissionOwner owner = new UriPermissionOwner(this, name);
10186            return owner.getExternalTokenLocked();
10187        }
10188    }
10189
10190    @Override
10191    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
10192        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
10193        synchronized(this) {
10194            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10195            if (r == null) {
10196                throw new IllegalArgumentException("Activity does not exist; token="
10197                        + activityToken);
10198            }
10199            return r.getUriPermissionsLocked().getExternalTokenLocked();
10200        }
10201    }
10202    /**
10203     * @param uri This uri must NOT contain an embedded userId.
10204     * @param sourceUserId The userId in which the uri is to be resolved.
10205     * @param targetUserId The userId of the app that receives the grant.
10206     */
10207    @Override
10208    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
10209            final int modeFlags, int sourceUserId, int targetUserId) {
10210        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
10211                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
10212                "grantUriPermissionFromOwner", null);
10213        synchronized(this) {
10214            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
10215            if (owner == null) {
10216                throw new IllegalArgumentException("Unknown owner: " + token);
10217            }
10218            if (fromUid != Binder.getCallingUid()) {
10219                if (Binder.getCallingUid() != myUid()) {
10220                    // Only system code can grant URI permissions on behalf
10221                    // of other users.
10222                    throw new SecurityException("nice try");
10223                }
10224            }
10225            if (targetPkg == null) {
10226                throw new IllegalArgumentException("null target");
10227            }
10228            if (uri == null) {
10229                throw new IllegalArgumentException("null uri");
10230            }
10231
10232            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
10233                    modeFlags, owner, targetUserId);
10234        }
10235    }
10236
10237    /**
10238     * @param uri This uri must NOT contain an embedded userId.
10239     * @param userId The userId in which the uri is to be resolved.
10240     */
10241    @Override
10242    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
10243        synchronized(this) {
10244            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
10245            if (owner == null) {
10246                throw new IllegalArgumentException("Unknown owner: " + token);
10247            }
10248
10249            if (uri == null) {
10250                owner.removeUriPermissionsLocked(mode);
10251            } else {
10252                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
10253                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
10254            }
10255        }
10256    }
10257
10258    private void schedulePersistUriGrants() {
10259        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
10260            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
10261                    10 * DateUtils.SECOND_IN_MILLIS);
10262        }
10263    }
10264
10265    private void writeGrantedUriPermissions() {
10266        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
10267
10268        final long startTime = SystemClock.uptimeMillis();
10269
10270        // Snapshot permissions so we can persist without lock
10271        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
10272        synchronized (this) {
10273            final int size = mGrantedUriPermissions.size();
10274            for (int i = 0; i < size; i++) {
10275                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10276                for (UriPermission perm : perms.values()) {
10277                    if (perm.persistedModeFlags != 0) {
10278                        persist.add(perm.snapshot());
10279                    }
10280                }
10281            }
10282        }
10283
10284        FileOutputStream fos = null;
10285        try {
10286            fos = mGrantFile.startWrite(startTime);
10287
10288            XmlSerializer out = new FastXmlSerializer();
10289            out.setOutput(fos, StandardCharsets.UTF_8.name());
10290            out.startDocument(null, true);
10291            out.startTag(null, TAG_URI_GRANTS);
10292            for (UriPermission.Snapshot perm : persist) {
10293                out.startTag(null, TAG_URI_GRANT);
10294                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
10295                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
10296                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
10297                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
10298                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
10299                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
10300                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
10301                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
10302                out.endTag(null, TAG_URI_GRANT);
10303            }
10304            out.endTag(null, TAG_URI_GRANTS);
10305            out.endDocument();
10306
10307            mGrantFile.finishWrite(fos);
10308        } catch (IOException e) {
10309            if (fos != null) {
10310                mGrantFile.failWrite(fos);
10311            }
10312        }
10313    }
10314
10315    @GuardedBy("this")
10316    private void readGrantedUriPermissionsLocked() {
10317        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
10318
10319        final long now = System.currentTimeMillis();
10320
10321        FileInputStream fis = null;
10322        try {
10323            fis = mGrantFile.openRead();
10324            final XmlPullParser in = Xml.newPullParser();
10325            in.setInput(fis, StandardCharsets.UTF_8.name());
10326
10327            int type;
10328            while ((type = in.next()) != END_DOCUMENT) {
10329                final String tag = in.getName();
10330                if (type == START_TAG) {
10331                    if (TAG_URI_GRANT.equals(tag)) {
10332                        final int sourceUserId;
10333                        final int targetUserId;
10334                        final int userHandle = readIntAttribute(in,
10335                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
10336                        if (userHandle != UserHandle.USER_NULL) {
10337                            // For backwards compatibility.
10338                            sourceUserId = userHandle;
10339                            targetUserId = userHandle;
10340                        } else {
10341                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
10342                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
10343                        }
10344                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
10345                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
10346                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
10347                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
10348                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
10349                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
10350
10351                        // Sanity check that provider still belongs to source package
10352                        // Both direct boot aware and unaware packages are fine as we
10353                        // will do filtering at query time to avoid multiple parsing.
10354                        final ProviderInfo pi = getProviderInfoLocked(
10355                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
10356                                        | MATCH_DIRECT_BOOT_UNAWARE);
10357                        if (pi != null && sourcePkg.equals(pi.packageName)) {
10358                            int targetUid = -1;
10359                            try {
10360                                targetUid = AppGlobals.getPackageManager().getPackageUid(
10361                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
10362                            } catch (RemoteException e) {
10363                            }
10364                            if (targetUid != -1) {
10365                                final UriPermission perm = findOrCreateUriPermissionLocked(
10366                                        sourcePkg, targetPkg, targetUid,
10367                                        new GrantUri(sourceUserId, uri, prefix));
10368                                perm.initPersistedModes(modeFlags, createdTime);
10369                            }
10370                        } else {
10371                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
10372                                    + " but instead found " + pi);
10373                        }
10374                    }
10375                }
10376            }
10377        } catch (FileNotFoundException e) {
10378            // Missing grants is okay
10379        } catch (IOException e) {
10380            Slog.wtf(TAG, "Failed reading Uri grants", e);
10381        } catch (XmlPullParserException e) {
10382            Slog.wtf(TAG, "Failed reading Uri grants", e);
10383        } finally {
10384            IoUtils.closeQuietly(fis);
10385        }
10386    }
10387
10388    /**
10389     * @param uri This uri must NOT contain an embedded userId.
10390     * @param toPackage Name of package whose uri is being granted to (if {@code null}, uses
10391     * calling uid)
10392     * @param userId The userId in which the uri is to be resolved.
10393     */
10394    @Override
10395    public void takePersistableUriPermission(Uri uri, final int modeFlags,
10396            @Nullable String toPackage, int userId) {
10397        final int uid;
10398        if (toPackage != null) {
10399            enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10400                    "takePersistableUriPermission");
10401            uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10402        } else {
10403            enforceNotIsolatedCaller("takePersistableUriPermission");
10404            uid = Binder.getCallingUid();
10405        }
10406
10407        Preconditions.checkFlagsArgument(modeFlags,
10408                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10409
10410        synchronized (this) {
10411            boolean persistChanged = false;
10412            GrantUri grantUri = new GrantUri(userId, uri, false);
10413
10414            UriPermission exactPerm = findUriPermissionLocked(uid, grantUri);
10415            UriPermission prefixPerm = findUriPermissionLocked(uid,
10416                    new GrantUri(userId, uri, true));
10417
10418            final boolean exactValid = (exactPerm != null)
10419                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
10420            final boolean prefixValid = (prefixPerm != null)
10421                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
10422
10423            if (!(exactValid || prefixValid)) {
10424                throw new SecurityException("No persistable permission grants found for UID "
10425                        + uid + " and Uri " + grantUri.toSafeString());
10426            }
10427
10428            if (exactValid) {
10429                persistChanged |= exactPerm.takePersistableModes(modeFlags);
10430            }
10431            if (prefixValid) {
10432                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
10433            }
10434
10435            persistChanged |= maybePrunePersistedUriGrantsLocked(uid);
10436
10437            if (persistChanged) {
10438                schedulePersistUriGrants();
10439            }
10440        }
10441    }
10442
10443    /**
10444     * @param uri This uri must NOT contain an embedded userId.
10445     * @param toPackage Name of the target package whose uri is being released (if {@code null},
10446     * uses calling uid)
10447     * @param userId The userId in which the uri is to be resolved.
10448     */
10449    @Override
10450    public void releasePersistableUriPermission(Uri uri, final int modeFlags,
10451            @Nullable String toPackage, int userId) {
10452
10453        final int uid;
10454        if (toPackage != null) {
10455            enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10456                    "releasePersistableUriPermission");
10457            uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10458        } else {
10459            enforceNotIsolatedCaller("releasePersistableUriPermission");
10460            uid = Binder.getCallingUid();
10461        }
10462
10463        Preconditions.checkFlagsArgument(modeFlags,
10464                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10465
10466        synchronized (this) {
10467            boolean persistChanged = false;
10468
10469            UriPermission exactPerm = findUriPermissionLocked(uid,
10470                    new GrantUri(userId, uri, false));
10471            UriPermission prefixPerm = findUriPermissionLocked(uid,
10472                    new GrantUri(userId, uri, true));
10473            if (exactPerm == null && prefixPerm == null && toPackage == null) {
10474                throw new SecurityException("No permission grants found for UID " + uid
10475                        + " and Uri " + uri.toSafeString());
10476            }
10477
10478            if (exactPerm != null) {
10479                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
10480                removeUriPermissionIfNeededLocked(exactPerm);
10481            }
10482            if (prefixPerm != null) {
10483                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
10484                removeUriPermissionIfNeededLocked(prefixPerm);
10485            }
10486
10487            if (persistChanged) {
10488                schedulePersistUriGrants();
10489            }
10490        }
10491    }
10492
10493    /**
10494     * Prune any older {@link UriPermission} for the given UID until outstanding
10495     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
10496     *
10497     * @return if any mutations occured that require persisting.
10498     */
10499    @GuardedBy("this")
10500    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
10501        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
10502        if (perms == null) return false;
10503        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
10504
10505        final ArrayList<UriPermission> persisted = Lists.newArrayList();
10506        for (UriPermission perm : perms.values()) {
10507            if (perm.persistedModeFlags != 0) {
10508                persisted.add(perm);
10509            }
10510        }
10511
10512        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
10513        if (trimCount <= 0) return false;
10514
10515        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
10516        for (int i = 0; i < trimCount; i++) {
10517            final UriPermission perm = persisted.get(i);
10518
10519            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10520                    "Trimming grant created at " + perm.persistedCreateTime);
10521
10522            perm.releasePersistableModes(~0);
10523            removeUriPermissionIfNeededLocked(perm);
10524        }
10525
10526        return true;
10527    }
10528
10529    @Override
10530    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
10531            String packageName, boolean incoming) {
10532        enforceNotIsolatedCaller("getPersistedUriPermissions");
10533        Preconditions.checkNotNull(packageName, "packageName");
10534
10535        final int callingUid = Binder.getCallingUid();
10536        final int callingUserId = UserHandle.getUserId(callingUid);
10537        final IPackageManager pm = AppGlobals.getPackageManager();
10538        try {
10539            final int packageUid = pm.getPackageUid(packageName,
10540                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
10541            if (packageUid != callingUid) {
10542                throw new SecurityException(
10543                        "Package " + packageName + " does not belong to calling UID " + callingUid);
10544            }
10545        } catch (RemoteException e) {
10546            throw new SecurityException("Failed to verify package name ownership");
10547        }
10548
10549        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10550        synchronized (this) {
10551            if (incoming) {
10552                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10553                        callingUid);
10554                if (perms == null) {
10555                    Slog.w(TAG, "No permission grants found for " + packageName);
10556                } else {
10557                    for (int j = 0; j < perms.size(); j++) {
10558                        final UriPermission perm = perms.valueAt(j);
10559                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
10560                            result.add(perm.buildPersistedPublicApiObject());
10561                        }
10562                    }
10563                }
10564            } else {
10565                final int size = mGrantedUriPermissions.size();
10566                for (int i = 0; i < size; i++) {
10567                    final ArrayMap<GrantUri, UriPermission> perms =
10568                            mGrantedUriPermissions.valueAt(i);
10569                    for (int j = 0; j < perms.size(); j++) {
10570                        final UriPermission perm = perms.valueAt(j);
10571                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
10572                            result.add(perm.buildPersistedPublicApiObject());
10573                        }
10574                    }
10575                }
10576            }
10577        }
10578        return new ParceledListSlice<android.content.UriPermission>(result);
10579    }
10580
10581    @Override
10582    public ParceledListSlice<GrantedUriPermission> getGrantedUriPermissions(
10583            @Nullable String packageName, int userId) {
10584        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10585                "getGrantedUriPermissions");
10586
10587        final List<GrantedUriPermission> result = new ArrayList<>();
10588        synchronized (this) {
10589            final int size = mGrantedUriPermissions.size();
10590            for (int i = 0; i < size; i++) {
10591                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10592                for (int j = 0; j < perms.size(); j++) {
10593                    final UriPermission perm = perms.valueAt(j);
10594                    if ((packageName == null || packageName.equals(perm.targetPkg))
10595                            && perm.targetUserId == userId
10596                            && perm.persistedModeFlags != 0) {
10597                        result.add(perm.buildGrantedUriPermission());
10598                    }
10599                }
10600            }
10601        }
10602        return new ParceledListSlice<>(result);
10603    }
10604
10605    @Override
10606    public void clearGrantedUriPermissions(String packageName, int userId) {
10607        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
10608                "clearGrantedUriPermissions");
10609        synchronized(this) {
10610            removeUriPermissionsForPackageLocked(packageName, userId, true, true);
10611        }
10612    }
10613
10614    @Override
10615    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
10616        synchronized (this) {
10617            ProcessRecord app =
10618                who != null ? getRecordForAppLocked(who) : null;
10619            if (app == null) return;
10620
10621            Message msg = Message.obtain();
10622            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
10623            msg.obj = app;
10624            msg.arg1 = waiting ? 1 : 0;
10625            mUiHandler.sendMessage(msg);
10626        }
10627    }
10628
10629    @Override
10630    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
10631        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
10632        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
10633        outInfo.availMem = getFreeMemory();
10634        outInfo.totalMem = getTotalMemory();
10635        outInfo.threshold = homeAppMem;
10636        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
10637        outInfo.hiddenAppThreshold = cachedAppMem;
10638        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
10639                ProcessList.SERVICE_ADJ);
10640        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
10641                ProcessList.VISIBLE_APP_ADJ);
10642        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
10643                ProcessList.FOREGROUND_APP_ADJ);
10644    }
10645
10646    // =========================================================
10647    // TASK MANAGEMENT
10648    // =========================================================
10649
10650    @Override
10651    public List<IBinder> getAppTasks(String callingPackage) {
10652        int callingUid = Binder.getCallingUid();
10653        long ident = Binder.clearCallingIdentity();
10654        try {
10655            synchronized(this) {
10656                return mRecentTasks.getAppTasksList(callingUid, callingPackage);
10657            }
10658        } finally {
10659            Binder.restoreCallingIdentity(ident);
10660        }
10661    }
10662
10663    @Override
10664    public List<RunningTaskInfo> getTasks(int maxNum) {
10665       return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
10666    }
10667
10668    @Override
10669    public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
10670            @WindowingMode int ignoreWindowingMode) {
10671        final int callingUid = Binder.getCallingUid();
10672        ArrayList<RunningTaskInfo> list = new ArrayList<>();
10673
10674        synchronized(this) {
10675            if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
10676
10677            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
10678                    callingUid);
10679            mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
10680                    ignoreWindowingMode, callingUid, allowed);
10681        }
10682
10683        return list;
10684    }
10685
10686    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
10687        if (mRecentTasks.isCallerRecents(callingUid)) {
10688            // Always allow the recents component to get tasks
10689            return true;
10690        }
10691
10692        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
10693                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
10694        if (!allowed) {
10695            if (checkPermission(android.Manifest.permission.GET_TASKS,
10696                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
10697                // Temporary compatibility: some existing apps on the system image may
10698                // still be requesting the old permission and not switched to the new
10699                // one; if so, we'll still allow them full access.  This means we need
10700                // to see if they are holding the old permission and are a system app.
10701                try {
10702                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
10703                        allowed = true;
10704                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10705                                + " is using old GET_TASKS but privileged; allowing");
10706                    }
10707                } catch (RemoteException e) {
10708                }
10709            }
10710        }
10711        if (!allowed) {
10712            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10713                    + " does not hold REAL_GET_TASKS; limiting output");
10714        }
10715        return allowed;
10716    }
10717
10718    @Override
10719    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
10720            int userId) {
10721        final int callingUid = Binder.getCallingUid();
10722        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
10723                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
10724        final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
10725                callingUid);
10726        final boolean detailed = checkCallingPermission(
10727                android.Manifest.permission.GET_DETAILED_TASKS)
10728                        == PackageManager.PERMISSION_GRANTED;
10729
10730        synchronized (this) {
10731            return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
10732                    callingUid);
10733        }
10734    }
10735
10736    @Override
10737    public ActivityManager.TaskDescription getTaskDescription(int id) {
10738        synchronized (this) {
10739            enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
10740            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10741                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10742            if (tr != null) {
10743                return tr.lastTaskDescription;
10744            }
10745        }
10746        return null;
10747    }
10748
10749    @Override
10750    public int addAppTask(IBinder activityToken, Intent intent,
10751            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10752        final int callingUid = Binder.getCallingUid();
10753        final long callingIdent = Binder.clearCallingIdentity();
10754
10755        try {
10756            synchronized (this) {
10757                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10758                if (r == null) {
10759                    throw new IllegalArgumentException("Activity does not exist; token="
10760                            + activityToken);
10761                }
10762                ComponentName comp = intent.getComponent();
10763                if (comp == null) {
10764                    throw new IllegalArgumentException("Intent " + intent
10765                            + " must specify explicit component");
10766                }
10767                if (thumbnail.getWidth() != mThumbnailWidth
10768                        || thumbnail.getHeight() != mThumbnailHeight) {
10769                    throw new IllegalArgumentException("Bad thumbnail size: got "
10770                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10771                            + mThumbnailWidth + "x" + mThumbnailHeight);
10772                }
10773                if (intent.getSelector() != null) {
10774                    intent.setSelector(null);
10775                }
10776                if (intent.getSourceBounds() != null) {
10777                    intent.setSourceBounds(null);
10778                }
10779                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10780                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10781                        // The caller has added this as an auto-remove task...  that makes no
10782                        // sense, so turn off auto-remove.
10783                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10784                    }
10785                }
10786                final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
10787                        STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
10788                if (ainfo.applicationInfo.uid != callingUid) {
10789                    throw new SecurityException(
10790                            "Can't add task for another application: target uid="
10791                            + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10792                }
10793
10794                final ActivityStack stack = r.getStack();
10795                final TaskRecord task = stack.createTaskRecord(
10796                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
10797                        null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
10798                if (!mRecentTasks.addToBottom(task)) {
10799                    // The app has too many tasks already and we can't add any more
10800                    stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
10801                    return INVALID_TASK_ID;
10802                }
10803                task.lastTaskDescription.copyFrom(description);
10804
10805                // TODO: Send the thumbnail to WM to store it.
10806
10807                return task.taskId;
10808            }
10809        } finally {
10810            Binder.restoreCallingIdentity(callingIdent);
10811        }
10812    }
10813
10814    @Override
10815    public Point getAppTaskThumbnailSize() {
10816        synchronized (this) {
10817            return new Point(mThumbnailWidth,  mThumbnailHeight);
10818        }
10819    }
10820
10821    @Override
10822    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10823        synchronized (this) {
10824            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10825            if (r != null) {
10826                r.setTaskDescription(td);
10827                final TaskRecord task = r.getTask();
10828                task.updateTaskDescription();
10829                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10830            }
10831        }
10832    }
10833
10834    @Override
10835    public void setTaskResizeable(int taskId, int resizeableMode) {
10836        synchronized (this) {
10837            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10838                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10839            if (task == null) {
10840                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10841                return;
10842            }
10843            task.setResizeMode(resizeableMode);
10844        }
10845    }
10846
10847    @Override
10848    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10849        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10850        long ident = Binder.clearCallingIdentity();
10851        try {
10852            synchronized (this) {
10853                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10854                if (task == null) {
10855                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10856                    return;
10857                }
10858                // Place the task in the right stack if it isn't there already based on
10859                // the requested bounds.
10860                // The stack transition logic is:
10861                // - a null bounds on a freeform task moves that task to fullscreen
10862                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10863                //   that task to freeform
10864                // - otherwise the task is not moved
10865                ActivityStack stack = task.getStack();
10866                if (!task.getWindowConfiguration().canResizeTask()) {
10867                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10868                }
10869                if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
10870                    stack = stack.getDisplay().getOrCreateStack(
10871                            WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10872                } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
10873                    stack = stack.getDisplay().getOrCreateStack(
10874                            WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
10875                }
10876
10877                // Reparent the task to the right stack if necessary
10878                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10879                if (stack != task.getStack()) {
10880                    // Defer resume until the task is resized below
10881                    task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10882                            DEFER_RESUME, "resizeTask");
10883                    preserveWindow = false;
10884                }
10885
10886                // After reparenting (which only resizes the task to the stack bounds), resize the
10887                // task to the actual bounds provided
10888                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10889            }
10890        } finally {
10891            Binder.restoreCallingIdentity(ident);
10892        }
10893    }
10894
10895    @Override
10896    public Rect getTaskBounds(int taskId) {
10897        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10898        long ident = Binder.clearCallingIdentity();
10899        Rect rect = new Rect();
10900        try {
10901            synchronized (this) {
10902                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10903                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10904                if (task == null) {
10905                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10906                    return rect;
10907                }
10908                if (task.getStack() != null) {
10909                    // Return the bounds from window manager since it will be adjusted for various
10910                    // things like the presense of a docked stack for tasks that aren't resizeable.
10911                    task.getWindowContainerBounds(rect);
10912                } else {
10913                    // Task isn't in window manager yet since it isn't associated with a stack.
10914                    // Return the persist value from activity manager
10915                    if (!task.matchParentBounds()) {
10916                        rect.set(task.getBounds());
10917                    } else if (task.mLastNonFullscreenBounds != null) {
10918                        rect.set(task.mLastNonFullscreenBounds);
10919                    }
10920                }
10921            }
10922        } finally {
10923            Binder.restoreCallingIdentity(ident);
10924        }
10925        return rect;
10926    }
10927
10928    @Override
10929    public void cancelTaskWindowTransition(int taskId) {
10930        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10931                "cancelTaskWindowTransition()");
10932        final long ident = Binder.clearCallingIdentity();
10933        try {
10934            synchronized (this) {
10935                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10936                        MATCH_TASK_IN_STACKS_ONLY);
10937                if (task == null) {
10938                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10939                    return;
10940                }
10941                task.cancelWindowTransition();
10942            }
10943        } finally {
10944            Binder.restoreCallingIdentity(ident);
10945        }
10946    }
10947
10948    @Override
10949    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10950        enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10951        final long ident = Binder.clearCallingIdentity();
10952        try {
10953            final TaskRecord task;
10954            synchronized (this) {
10955                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10956                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10957                if (task == null) {
10958                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10959                    return null;
10960                }
10961            }
10962            // Don't call this while holding the lock as this operation might hit the disk.
10963            return task.getSnapshot(reducedResolution);
10964        } finally {
10965            Binder.restoreCallingIdentity(ident);
10966        }
10967    }
10968
10969    @Override
10970    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10971        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10972                userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
10973
10974        final File passedIconFile = new File(filePath);
10975        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10976                passedIconFile.getName());
10977        if (!legitIconFile.getPath().equals(filePath)
10978                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10979            throw new IllegalArgumentException("Bad file path: " + filePath
10980                    + " passed for userId " + userId);
10981        }
10982        return mRecentTasks.getTaskDescriptionIcon(filePath);
10983    }
10984
10985    @Override
10986    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10987            throws RemoteException {
10988        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
10989        final ActivityOptions activityOptions = safeOptions != null
10990                ? safeOptions.getOptions(mStackSupervisor)
10991                : null;
10992        if (activityOptions == null
10993                || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
10994                || activityOptions.getCustomInPlaceResId() == 0) {
10995            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10996                    "with valid animation");
10997        }
10998        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10999        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
11000                activityOptions.getCustomInPlaceResId());
11001        mWindowManager.executeAppTransition();
11002    }
11003
11004    @Override
11005    public void removeStack(int stackId) {
11006        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
11007        synchronized (this) {
11008            final long ident = Binder.clearCallingIdentity();
11009            try {
11010                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11011                if (stack == null) {
11012                    Slog.w(TAG, "removeStack: No stack with id=" + stackId);
11013                    return;
11014                }
11015                if (!stack.isActivityTypeStandardOrUndefined()) {
11016                    throw new IllegalArgumentException(
11017                            "Removing non-standard stack is not allowed.");
11018                }
11019                mStackSupervisor.removeStack(stack);
11020            } finally {
11021                Binder.restoreCallingIdentity(ident);
11022            }
11023        }
11024    }
11025
11026    /**
11027     * Removes stacks in the input windowing modes from the system if they are of activity type
11028     * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
11029     */
11030    @Override
11031    public void removeStacksInWindowingModes(int[] windowingModes) {
11032        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11033                "removeStacksInWindowingModes()");
11034        synchronized (this) {
11035            final long ident = Binder.clearCallingIdentity();
11036            try {
11037                mStackSupervisor.removeStacksInWindowingModes(windowingModes);
11038            } finally {
11039                Binder.restoreCallingIdentity(ident);
11040            }
11041        }
11042    }
11043
11044    @Override
11045    public void removeStacksWithActivityTypes(int[] activityTypes) {
11046        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11047                "removeStacksWithActivityTypes()");
11048        synchronized (this) {
11049            final long ident = Binder.clearCallingIdentity();
11050            try {
11051                mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
11052            } finally {
11053                Binder.restoreCallingIdentity(ident);
11054            }
11055        }
11056    }
11057
11058    @Override
11059    public void moveStackToDisplay(int stackId, int displayId) {
11060        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
11061
11062        synchronized (this) {
11063            final long ident = Binder.clearCallingIdentity();
11064            try {
11065                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
11066                        + " to displayId=" + displayId);
11067                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
11068            } finally {
11069                Binder.restoreCallingIdentity(ident);
11070            }
11071        }
11072    }
11073
11074    @Override
11075    public boolean removeTask(int taskId) {
11076        enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
11077        synchronized (this) {
11078            final long ident = Binder.clearCallingIdentity();
11079            try {
11080                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
11081                        "remove-task");
11082            } finally {
11083                Binder.restoreCallingIdentity(ident);
11084            }
11085        }
11086    }
11087
11088    /**
11089     * TODO: Add mController hook
11090     */
11091    @Override
11092    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
11093        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
11094
11095        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
11096        synchronized(this) {
11097            moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
11098                    false /* fromRecents */);
11099        }
11100    }
11101
11102    void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
11103            boolean fromRecents) {
11104
11105        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
11106                Binder.getCallingUid(), -1, -1, "Task to front")) {
11107            SafeActivityOptions.abort(options);
11108            return;
11109        }
11110        final long origId = Binder.clearCallingIdentity();
11111        try {
11112            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11113            if (task == null) {
11114                Slog.d(TAG, "Could not find task for id: "+ taskId);
11115                return;
11116            }
11117            if (mLockTaskController.isLockTaskModeViolation(task)) {
11118                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
11119                return;
11120            }
11121            ActivityOptions realOptions = options != null
11122                    ? options.getOptions(mStackSupervisor)
11123                    : null;
11124            mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
11125                    false /* forceNonResizable */);
11126
11127            final ActivityRecord topActivity = task.getTopActivity();
11128            if (topActivity != null) {
11129
11130                // We are reshowing a task, use a starting window to hide the initial draw delay
11131                // so the transition can start earlier.
11132                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
11133                        true /* taskSwitch */, fromRecents);
11134            }
11135        } finally {
11136            Binder.restoreCallingIdentity(origId);
11137        }
11138        SafeActivityOptions.abort(options);
11139    }
11140
11141    /**
11142     * Attempts to move a task backwards in z-order (the order of activities within the task is
11143     * unchanged).
11144     *
11145     * There are several possible results of this call:
11146     * - if the task is locked, then we will show the lock toast
11147     * - if there is a task behind the provided task, then that task is made visible and resumed as
11148     *   this task is moved to the back
11149     * - otherwise, if there are no other tasks in the stack:
11150     *     - if this task is in the pinned stack, then we remove the stack completely, which will
11151     *       have the effect of moving the task to the top or bottom of the fullscreen stack
11152     *       (depending on whether it is visible)
11153     *     - otherwise, we simply return home and hide this task
11154     *
11155     * @param token A reference to the activity we wish to move
11156     * @param nonRoot If false then this only works if the activity is the root
11157     *                of a task; if true it will work for any activity in a task.
11158     * @return Returns true if the move completed, false if not.
11159     */
11160    @Override
11161    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
11162        enforceNotIsolatedCaller("moveActivityTaskToBack");
11163        synchronized(this) {
11164            final long origId = Binder.clearCallingIdentity();
11165            try {
11166                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
11167                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11168                if (task != null) {
11169                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
11170                }
11171            } finally {
11172                Binder.restoreCallingIdentity(origId);
11173            }
11174        }
11175        return false;
11176    }
11177
11178    @Override
11179    public void moveTaskBackwards(int task) {
11180        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
11181                "moveTaskBackwards()");
11182
11183        synchronized(this) {
11184            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
11185                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
11186                return;
11187            }
11188            final long origId = Binder.clearCallingIdentity();
11189            moveTaskBackwardsLocked(task);
11190            Binder.restoreCallingIdentity(origId);
11191        }
11192    }
11193
11194    private final void moveTaskBackwardsLocked(int task) {
11195        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
11196    }
11197
11198    @Override
11199    public int createStackOnDisplay(int displayId) throws RemoteException {
11200        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
11201        synchronized (this) {
11202            final ActivityDisplay display =
11203                    mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
11204            if (display == null) {
11205                return INVALID_STACK_ID;
11206            }
11207            // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
11208            final ActivityStack stack = display.createStack(
11209                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
11210                    ON_TOP);
11211            return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
11212        }
11213    }
11214
11215    @Override
11216    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
11217        synchronized (this) {
11218            final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
11219            if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
11220                return stack.mDisplayId;
11221            }
11222            return DEFAULT_DISPLAY;
11223        }
11224    }
11225
11226    @Override
11227    public void exitFreeformMode(IBinder token) throws RemoteException {
11228        synchronized (this) {
11229            long ident = Binder.clearCallingIdentity();
11230            try {
11231                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11232                if (r == null) {
11233                    throw new IllegalArgumentException(
11234                            "exitFreeformMode: No activity record matching token=" + token);
11235                }
11236
11237                final ActivityStack stack = r.getStack();
11238                if (stack == null || !stack.inFreeformWindowingMode()) {
11239                    throw new IllegalStateException(
11240                            "exitFreeformMode: You can only go fullscreen from freeform.");
11241                }
11242
11243                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11244            } finally {
11245                Binder.restoreCallingIdentity(ident);
11246            }
11247        }
11248    }
11249
11250    @Override
11251    public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
11252        if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
11253            setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
11254                    toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
11255            return;
11256        }
11257        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
11258        synchronized (this) {
11259            final long ident = Binder.clearCallingIdentity();
11260            try {
11261                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11262                if (task == null) {
11263                    Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
11264                    return;
11265                }
11266
11267                if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
11268                        + " to windowingMode=" + windowingMode + " toTop=" + toTop);
11269
11270                if (!task.isActivityTypeStandardOrUndefined()) {
11271                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11272                            + " non-standard task " + taskId + " to windowing mode="
11273                            + windowingMode);
11274                }
11275
11276                final ActivityStack stack = task.getStack();
11277                if (toTop) {
11278                    stack.moveToFront("setTaskWindowingMode", task);
11279                }
11280                stack.setWindowingMode(windowingMode);
11281            } finally {
11282                Binder.restoreCallingIdentity(ident);
11283            }
11284        }
11285    }
11286
11287    /**
11288     * Moves the specified task to the primary-split-screen stack.
11289     *
11290     * @param taskId Id of task to move.
11291     * @param createMode The mode the primary split screen stack should be created in if it doesn't
11292     *                   exist already. See
11293     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
11294     *                   and
11295     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
11296     * @param toTop If the task and stack should be moved to the top.
11297     * @param animate Whether we should play an animation for the moving the task.
11298     * @param initialBounds If the primary stack gets created, it will use these bounds for the
11299     *                      stack. Pass {@code null} to use default bounds.
11300     * @param showRecents If the recents activity should be shown on the other side of the task
11301     *                    going into split-screen mode.
11302     */
11303    @Override
11304    public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
11305            boolean animate, Rect initialBounds, boolean showRecents) {
11306        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11307                "setTaskWindowingModeSplitScreenPrimary()");
11308        synchronized (this) {
11309            long ident = Binder.clearCallingIdentity();
11310            try {
11311                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11312                if (task == null) {
11313                    Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
11314                    return false;
11315                }
11316                if (DEBUG_STACK) Slog.d(TAG_STACK,
11317                        "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
11318                        + " to createMode=" + createMode + " toTop=" + toTop);
11319                if (!task.isActivityTypeStandardOrUndefined()) {
11320                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11321                            + " non-standard task " + taskId + " to split-screen windowing mode");
11322                }
11323
11324                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
11325                final int windowingMode = task.getWindowingMode();
11326                final ActivityStack stack = task.getStack();
11327                if (toTop) {
11328                    stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
11329                }
11330                stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
11331                        false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */);
11332                return windowingMode != task.getWindowingMode();
11333            } finally {
11334                Binder.restoreCallingIdentity(ident);
11335            }
11336        }
11337    }
11338
11339    @Override
11340    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
11341        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
11342        synchronized (this) {
11343            long ident = Binder.clearCallingIdentity();
11344            try {
11345                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11346                if (task == null) {
11347                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
11348                    return;
11349                }
11350
11351                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
11352                        + " to stackId=" + stackId + " toTop=" + toTop);
11353
11354                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11355                if (stack == null) {
11356                    throw new IllegalStateException(
11357                            "moveTaskToStack: No stack for stackId=" + stackId);
11358                }
11359                if (!stack.isActivityTypeStandardOrUndefined()) {
11360                    throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
11361                            + taskId + " to stack " + stackId);
11362                }
11363                if (stack.inSplitScreenPrimaryWindowingMode()) {
11364                    mWindowManager.setDockedStackCreateState(
11365                            SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
11366                }
11367                task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
11368                        "moveTaskToStack");
11369            } finally {
11370                Binder.restoreCallingIdentity(ident);
11371            }
11372        }
11373    }
11374
11375    /**
11376     * Dismisses split-screen multi-window mode.
11377     * @param toTop If true the current primary split-screen stack will be placed or left on top.
11378     */
11379    @Override
11380    public void dismissSplitScreenMode(boolean toTop) {
11381        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
11382        final long ident = Binder.clearCallingIdentity();
11383        try {
11384            synchronized (this) {
11385                final ActivityStack stack =
11386                        mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
11387                if (stack == null) {
11388                    Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
11389                    return;
11390                }
11391
11392                if (toTop) {
11393                    // Caller wants the current split-screen primary stack to be the top stack after
11394                    // it goes fullscreen, so move it to the front.
11395                    stack.moveToFront("dismissSplitScreenMode");
11396                } else if (mStackSupervisor.isFocusedStack(stack)) {
11397                    // In this case the current split-screen primary stack shouldn't be the top
11398                    // stack after it goes fullscreen, but it current has focus, so we move the
11399                    // focus to the top-most split-screen secondary stack next to it.
11400                    final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
11401                            WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
11402                    if (otherStack != null) {
11403                        otherStack.moveToFront("dismissSplitScreenMode_other");
11404                    }
11405                }
11406
11407                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11408            }
11409        } finally {
11410            Binder.restoreCallingIdentity(ident);
11411        }
11412    }
11413
11414    /**
11415     * Dismisses Pip
11416     * @param animate True if the dismissal should be animated.
11417     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
11418     *                          default animation duration should be used.
11419     */
11420    @Override
11421    public void dismissPip(boolean animate, int animationDuration) {
11422        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
11423        final long ident = Binder.clearCallingIdentity();
11424        try {
11425            synchronized (this) {
11426                final PinnedActivityStack stack =
11427                        mStackSupervisor.getDefaultDisplay().getPinnedStack();
11428                if (stack == null) {
11429                    Slog.w(TAG, "dismissPip: pinned stack not found.");
11430                    return;
11431                }
11432                if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11433                    throw new IllegalArgumentException("Stack: " + stack
11434                            + " doesn't support animated resize.");
11435                }
11436                if (animate) {
11437                    stack.animateResizePinnedStack(null /* sourceHintBounds */,
11438                            null /* destBounds */, animationDuration, false /* fromFullscreen */);
11439                } else {
11440                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
11441                }
11442            }
11443        } finally {
11444            Binder.restoreCallingIdentity(ident);
11445        }
11446    }
11447
11448    /**
11449     * Moves the top activity in the input stackId to the pinned stack.
11450     *
11451     * @param stackId Id of stack to move the top activity to pinned stack.
11452     * @param bounds Bounds to use for pinned stack.
11453     *
11454     * @return True if the top activity of the input stack was successfully moved to the pinned
11455     *          stack.
11456     */
11457    @Override
11458    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
11459        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11460                "moveTopActivityToPinnedStack()");
11461        synchronized (this) {
11462            if (!mSupportsPictureInPicture) {
11463                throw new IllegalStateException("moveTopActivityToPinnedStack:"
11464                        + "Device doesn't support picture-in-picture mode");
11465            }
11466
11467            long ident = Binder.clearCallingIdentity();
11468            try {
11469                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
11470            } finally {
11471                Binder.restoreCallingIdentity(ident);
11472            }
11473        }
11474    }
11475
11476    @Override
11477    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
11478            boolean preserveWindows, boolean animate, int animationDuration) {
11479        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
11480        long ident = Binder.clearCallingIdentity();
11481        try {
11482            synchronized (this) {
11483                if (animate) {
11484                    final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
11485                    if (stack == null) {
11486                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11487                        return;
11488                    }
11489                    if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11490                        throw new IllegalArgumentException("Stack: " + stackId
11491                                + " doesn't support animated resize.");
11492                    }
11493                    stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
11494                            animationDuration, false /* fromFullscreen */);
11495                } else {
11496                    final ActivityStack stack = mStackSupervisor.getStack(stackId);
11497                    if (stack == null) {
11498                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11499                        return;
11500                    }
11501                    mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
11502                            null /* tempTaskInsetBounds */, preserveWindows,
11503                            allowResizeInDockedMode, !DEFER_RESUME);
11504                }
11505            }
11506        } finally {
11507            Binder.restoreCallingIdentity(ident);
11508        }
11509    }
11510
11511    @Override
11512    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
11513            Rect tempDockedTaskInsetBounds,
11514            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
11515        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
11516        long ident = Binder.clearCallingIdentity();
11517        try {
11518            synchronized (this) {
11519                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
11520                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
11521                        PRESERVE_WINDOWS);
11522            }
11523        } finally {
11524            Binder.restoreCallingIdentity(ident);
11525        }
11526    }
11527
11528    @Override
11529    public void setSplitScreenResizing(boolean resizing) {
11530        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
11531        final long ident = Binder.clearCallingIdentity();
11532        try {
11533            synchronized (this) {
11534                mStackSupervisor.setSplitScreenResizing(resizing);
11535            }
11536        } finally {
11537            Binder.restoreCallingIdentity(ident);
11538        }
11539    }
11540
11541    @Override
11542    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
11543        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
11544        final long ident = Binder.clearCallingIdentity();
11545        try {
11546            synchronized (this) {
11547                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
11548            }
11549        } finally {
11550            Binder.restoreCallingIdentity(ident);
11551        }
11552    }
11553
11554    /**
11555     * Try to place task to provided position. The final position might be different depending on
11556     * current user and stacks state. The task will be moved to target stack if it's currently in
11557     * different stack.
11558     */
11559    @Override
11560    public void positionTaskInStack(int taskId, int stackId, int position) {
11561        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
11562        synchronized (this) {
11563            long ident = Binder.clearCallingIdentity();
11564            try {
11565                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
11566                        + taskId + " in stackId=" + stackId + " at position=" + position);
11567                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11568                if (task == null) {
11569                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
11570                            + taskId);
11571                }
11572
11573                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11574
11575                if (stack == null) {
11576                    throw new IllegalArgumentException("positionTaskInStack: no stack for id="
11577                            + stackId);
11578                }
11579                if (!stack.isActivityTypeStandardOrUndefined()) {
11580                    throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
11581                            + " the position of task " + taskId + " in/to non-standard stack");
11582                }
11583
11584                // TODO: Have the callers of this API call a separate reparent method if that is
11585                // what they intended to do vs. having this method also do reparenting.
11586                if (task.getStack() == stack) {
11587                    // Change position in current stack.
11588                    stack.positionChildAt(task, position);
11589                } else {
11590                    // Reparent to new stack.
11591                    task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
11592                            !DEFER_RESUME, "positionTaskInStack");
11593                }
11594            } finally {
11595                Binder.restoreCallingIdentity(ident);
11596            }
11597        }
11598    }
11599
11600    @Override
11601    public List<StackInfo> getAllStackInfos() {
11602        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
11603        long ident = Binder.clearCallingIdentity();
11604        try {
11605            synchronized (this) {
11606                return mStackSupervisor.getAllStackInfosLocked();
11607            }
11608        } finally {
11609            Binder.restoreCallingIdentity(ident);
11610        }
11611    }
11612
11613    @Override
11614    public StackInfo getStackInfo(int windowingMode, int activityType) {
11615        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
11616        long ident = Binder.clearCallingIdentity();
11617        try {
11618            synchronized (this) {
11619                return mStackSupervisor.getStackInfo(windowingMode, activityType);
11620            }
11621        } finally {
11622            Binder.restoreCallingIdentity(ident);
11623        }
11624    }
11625
11626    @Override
11627    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
11628        synchronized(this) {
11629            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
11630        }
11631    }
11632
11633    @Override
11634    public void updateDeviceOwner(String packageName) {
11635        final int callingUid = Binder.getCallingUid();
11636        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11637            throw new SecurityException("updateDeviceOwner called from non-system process");
11638        }
11639        synchronized (this) {
11640            mDeviceOwnerName = packageName;
11641        }
11642    }
11643
11644    @Override
11645    public void updateLockTaskPackages(int userId, String[] packages) {
11646        final int callingUid = Binder.getCallingUid();
11647        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11648            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11649                    "updateLockTaskPackages()");
11650        }
11651        synchronized (this) {
11652            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
11653                    Arrays.toString(packages));
11654            mLockTaskController.updateLockTaskPackages(userId, packages);
11655        }
11656    }
11657
11658    @Override
11659    public void updateLockTaskFeatures(int userId, int flags) {
11660        final int callingUid = Binder.getCallingUid();
11661        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11662            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11663                    "updateLockTaskFeatures()");
11664        }
11665        synchronized (this) {
11666            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
11667                    Integer.toHexString(flags));
11668            mLockTaskController.updateLockTaskFeatures(userId, flags);
11669        }
11670    }
11671
11672    private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
11673        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
11674        if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
11675            return;
11676        }
11677
11678        final ActivityStack stack = mStackSupervisor.getFocusedStack();
11679        if (stack == null || task != stack.topTask()) {
11680            throw new IllegalArgumentException("Invalid task, not in foreground");
11681        }
11682
11683        // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
11684        // system or a specific app.
11685        // * System-initiated requests will only start the pinned mode (screen pinning)
11686        // * App-initiated requests
11687        //   - will put the device in fully locked mode (LockTask), if the app is whitelisted
11688        //   - will start the pinned mode, otherwise
11689        final int callingUid = Binder.getCallingUid();
11690        long ident = Binder.clearCallingIdentity();
11691        try {
11692            // When a task is locked, dismiss the pinned stack if it exists
11693            mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
11694
11695            mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
11696        } finally {
11697            Binder.restoreCallingIdentity(ident);
11698        }
11699    }
11700
11701    @Override
11702    public void startLockTaskModeByToken(IBinder token) {
11703        synchronized (this) {
11704            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11705            if (r == null) {
11706                return;
11707            }
11708            startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
11709        }
11710    }
11711
11712    @Override
11713    public void startSystemLockTaskMode(int taskId) throws RemoteException {
11714        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11715        // This makes inner call to look as if it was initiated by system.
11716        long ident = Binder.clearCallingIdentity();
11717        try {
11718            synchronized (this) {
11719                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11720
11721                // When starting lock task mode the stack must be in front and focused
11722                task.getStack().moveToFront("startSystemLockTaskMode");
11723                startLockTaskModeLocked(task, true /* isSystemCaller */);
11724            }
11725        } finally {
11726            Binder.restoreCallingIdentity(ident);
11727        }
11728    }
11729
11730    @Override
11731    public void stopLockTaskModeByToken(IBinder token) {
11732        synchronized (this) {
11733            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11734            if (r == null) {
11735                return;
11736            }
11737            stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
11738        }
11739    }
11740
11741    /**
11742     * This API should be called by SystemUI only when user perform certain action to dismiss
11743     * lock task mode. We should only dismiss pinned lock task mode in this case.
11744     */
11745    @Override
11746    public void stopSystemLockTaskMode() throws RemoteException {
11747        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
11748        stopLockTaskModeInternal(null, true /* isSystemCaller */);
11749    }
11750
11751    private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
11752        final int callingUid = Binder.getCallingUid();
11753        long ident = Binder.clearCallingIdentity();
11754        try {
11755            synchronized (this) {
11756                mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
11757            }
11758            // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
11759            // task and jumping straight into a call in the case of emergency call back.
11760            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11761            if (tm != null) {
11762                tm.showInCallScreen(false);
11763            }
11764        } finally {
11765            Binder.restoreCallingIdentity(ident);
11766        }
11767    }
11768
11769    @Override
11770    public boolean isInLockTaskMode() {
11771        return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
11772    }
11773
11774    @Override
11775    public int getLockTaskModeState() {
11776        synchronized (this) {
11777            return mLockTaskController.getLockTaskModeState();
11778        }
11779    }
11780
11781    @Override
11782    public void showLockTaskEscapeMessage(IBinder token) {
11783        synchronized (this) {
11784            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11785            if (r == null) {
11786                return;
11787            }
11788            mLockTaskController.showLockTaskToast();
11789        }
11790    }
11791
11792    @Override
11793    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11794            throws RemoteException {
11795        synchronized (this) {
11796            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11797            if (r == null) {
11798                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11799                        + token);
11800                return;
11801            }
11802            final long origId = Binder.clearCallingIdentity();
11803            try {
11804                r.setDisablePreviewScreenshots(disable);
11805            } finally {
11806                Binder.restoreCallingIdentity(origId);
11807            }
11808        }
11809    }
11810
11811    // =========================================================
11812    // CONTENT PROVIDERS
11813    // =========================================================
11814
11815    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11816        List<ProviderInfo> providers = null;
11817        try {
11818            providers = AppGlobals.getPackageManager()
11819                    .queryContentProviders(app.processName, app.uid,
11820                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11821                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11822                    .getList();
11823        } catch (RemoteException ex) {
11824        }
11825        if (DEBUG_MU) Slog.v(TAG_MU,
11826                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11827        int userId = app.userId;
11828        if (providers != null) {
11829            int N = providers.size();
11830            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11831            for (int i=0; i<N; i++) {
11832                // TODO: keep logic in sync with installEncryptionUnawareProviders
11833                ProviderInfo cpi =
11834                    (ProviderInfo)providers.get(i);
11835                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11836                        cpi.name, cpi.flags);
11837                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11838                    // This is a singleton provider, but a user besides the
11839                    // default user is asking to initialize a process it runs
11840                    // in...  well, no, it doesn't actually run in this process,
11841                    // it runs in the process of the default user.  Get rid of it.
11842                    providers.remove(i);
11843                    N--;
11844                    i--;
11845                    continue;
11846                }
11847
11848                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11849                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11850                if (cpr == null) {
11851                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11852                    mProviderMap.putProviderByClass(comp, cpr);
11853                }
11854                if (DEBUG_MU) Slog.v(TAG_MU,
11855                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11856                app.pubProviders.put(cpi.name, cpr);
11857                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11858                    // Don't add this if it is a platform component that is marked
11859                    // to run in multiple processes, because this is actually
11860                    // part of the framework so doesn't make sense to track as a
11861                    // separate apk in the process.
11862                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11863                            mProcessStats);
11864                }
11865                notifyPackageUse(cpi.applicationInfo.packageName,
11866                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11867            }
11868        }
11869        return providers;
11870    }
11871
11872    /**
11873     * Check if the calling UID has a possible chance at accessing the provider
11874     * at the given authority and user.
11875     */
11876    public String checkContentProviderAccess(String authority, int userId) {
11877        if (userId == UserHandle.USER_ALL) {
11878            mContext.enforceCallingOrSelfPermission(
11879                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11880            userId = UserHandle.getCallingUserId();
11881        }
11882
11883        ProviderInfo cpi = null;
11884        try {
11885            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11886                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11887                            | PackageManager.MATCH_DISABLED_COMPONENTS
11888                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11889                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11890                    userId);
11891        } catch (RemoteException ignored) {
11892        }
11893        if (cpi == null) {
11894            return "Failed to find provider " + authority + " for user " + userId
11895                    + "; expected to find a valid ContentProvider for this authority";
11896        }
11897
11898        ProcessRecord r = null;
11899        synchronized (mPidsSelfLocked) {
11900            r = mPidsSelfLocked.get(Binder.getCallingPid());
11901        }
11902        if (r == null) {
11903            return "Failed to find PID " + Binder.getCallingPid();
11904        }
11905
11906        synchronized (this) {
11907            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11908        }
11909    }
11910
11911    /**
11912     * Check if {@link ProcessRecord} has a possible chance at accessing the
11913     * given {@link ProviderInfo}. Final permission checking is always done
11914     * in {@link ContentProvider}.
11915     */
11916    private final String checkContentProviderPermissionLocked(
11917            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11918        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11919        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11920        boolean checkedGrants = false;
11921        if (checkUser) {
11922            // Looking for cross-user grants before enforcing the typical cross-users permissions
11923            int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
11924            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11925                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11926                    return null;
11927                }
11928                checkedGrants = true;
11929            }
11930            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11931                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11932            if (userId != tmpTargetUserId) {
11933                // When we actually went to determine the final targer user ID, this ended
11934                // up different than our initial check for the authority.  This is because
11935                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11936                // SELF.  So we need to re-check the grants again.
11937                checkedGrants = false;
11938            }
11939        }
11940        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11941                cpi.applicationInfo.uid, cpi.exported)
11942                == PackageManager.PERMISSION_GRANTED) {
11943            return null;
11944        }
11945        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11946                cpi.applicationInfo.uid, cpi.exported)
11947                == PackageManager.PERMISSION_GRANTED) {
11948            return null;
11949        }
11950
11951        PathPermission[] pps = cpi.pathPermissions;
11952        if (pps != null) {
11953            int i = pps.length;
11954            while (i > 0) {
11955                i--;
11956                PathPermission pp = pps[i];
11957                String pprperm = pp.getReadPermission();
11958                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11959                        cpi.applicationInfo.uid, cpi.exported)
11960                        == PackageManager.PERMISSION_GRANTED) {
11961                    return null;
11962                }
11963                String ppwperm = pp.getWritePermission();
11964                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11965                        cpi.applicationInfo.uid, cpi.exported)
11966                        == PackageManager.PERMISSION_GRANTED) {
11967                    return null;
11968                }
11969            }
11970        }
11971        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11972            return null;
11973        }
11974
11975        final String suffix;
11976        if (!cpi.exported) {
11977            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11978        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11979            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11980        } else {
11981            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11982        }
11983        final String msg = "Permission Denial: opening provider " + cpi.name
11984                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11985                + ", uid=" + callingUid + ")" + suffix;
11986        Slog.w(TAG, msg);
11987        return msg;
11988    }
11989
11990    /**
11991     * Returns if the ContentProvider has granted a uri to callingUid
11992     */
11993    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11994        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11995        if (perms != null) {
11996            for (int i=perms.size()-1; i>=0; i--) {
11997                GrantUri grantUri = perms.keyAt(i);
11998                if (grantUri.sourceUserId == userId || !checkUser) {
11999                    if (matchesProvider(grantUri.uri, cpi)) {
12000                        return true;
12001                    }
12002                }
12003            }
12004        }
12005        return false;
12006    }
12007
12008    /**
12009     * Returns true if the uri authority is one of the authorities specified in the provider.
12010     */
12011    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
12012        String uriAuth = uri.getAuthority();
12013        String cpiAuth = cpi.authority;
12014        if (cpiAuth.indexOf(';') == -1) {
12015            return cpiAuth.equals(uriAuth);
12016        }
12017        String[] cpiAuths = cpiAuth.split(";");
12018        int length = cpiAuths.length;
12019        for (int i = 0; i < length; i++) {
12020            if (cpiAuths[i].equals(uriAuth)) return true;
12021        }
12022        return false;
12023    }
12024
12025    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
12026            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
12027        if (r != null) {
12028            for (int i=0; i<r.conProviders.size(); i++) {
12029                ContentProviderConnection conn = r.conProviders.get(i);
12030                if (conn.provider == cpr) {
12031                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
12032                            "Adding provider requested by "
12033                            + r.processName + " from process "
12034                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
12035                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
12036                    if (stable) {
12037                        conn.stableCount++;
12038                        conn.numStableIncs++;
12039                    } else {
12040                        conn.unstableCount++;
12041                        conn.numUnstableIncs++;
12042                    }
12043                    return conn;
12044                }
12045            }
12046            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
12047            if (stable) {
12048                conn.stableCount = 1;
12049                conn.numStableIncs = 1;
12050            } else {
12051                conn.unstableCount = 1;
12052                conn.numUnstableIncs = 1;
12053            }
12054            cpr.connections.add(conn);
12055            r.conProviders.add(conn);
12056            startAssociationLocked(r.uid, r.processName, r.curProcState,
12057                    cpr.uid, cpr.name, cpr.info.processName);
12058            return conn;
12059        }
12060        cpr.addExternalProcessHandleLocked(externalProcessToken);
12061        return null;
12062    }
12063
12064    boolean decProviderCountLocked(ContentProviderConnection conn,
12065            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
12066        if (conn != null) {
12067            cpr = conn.provider;
12068            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
12069                    "Removing provider requested by "
12070                    + conn.client.processName + " from process "
12071                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
12072                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
12073            if (stable) {
12074                conn.stableCount--;
12075            } else {
12076                conn.unstableCount--;
12077            }
12078            if (conn.stableCount == 0 && conn.unstableCount == 0) {
12079                cpr.connections.remove(conn);
12080                conn.client.conProviders.remove(conn);
12081                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
12082                    // The client is more important than last activity -- note the time this
12083                    // is happening, so we keep the old provider process around a bit as last
12084                    // activity to avoid thrashing it.
12085                    if (cpr.proc != null) {
12086                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
12087                    }
12088                }
12089                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
12090                return true;
12091            }
12092            return false;
12093        }
12094        cpr.removeExternalProcessHandleLocked(externalProcessToken);
12095        return false;
12096    }
12097
12098    private void checkTime(long startTime, String where) {
12099        long now = SystemClock.uptimeMillis();
12100        if ((now-startTime) > 50) {
12101            // If we are taking more than 50ms, log about it.
12102            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
12103        }
12104    }
12105
12106    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
12107            PROC_SPACE_TERM,
12108            PROC_SPACE_TERM|PROC_PARENS,
12109            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
12110    };
12111
12112    private final long[] mProcessStateStatsLongs = new long[1];
12113
12114    private boolean isProcessAliveLocked(ProcessRecord proc) {
12115        if (proc.pid <= 0) {
12116            if (DEBUG_OOM_ADJ) Slog.d(TAG, "Process hasn't started yet: " + proc);
12117            return false;
12118        }
12119        if (proc.procStatFile == null) {
12120            proc.procStatFile = "/proc/" + proc.pid + "/stat";
12121        }
12122        mProcessStateStatsLongs[0] = 0;
12123        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
12124                mProcessStateStatsLongs, null)) {
12125            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
12126            return false;
12127        }
12128        final long state = mProcessStateStatsLongs[0];
12129        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
12130                + (char)state);
12131        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
12132    }
12133
12134    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
12135            String name, IBinder token, boolean stable, int userId) {
12136        ContentProviderRecord cpr;
12137        ContentProviderConnection conn = null;
12138        ProviderInfo cpi = null;
12139
12140        synchronized(this) {
12141            long startTime = SystemClock.uptimeMillis();
12142
12143            ProcessRecord r = null;
12144            if (caller != null) {
12145                r = getRecordForAppLocked(caller);
12146                if (r == null) {
12147                    throw new SecurityException(
12148                            "Unable to find app for caller " + caller
12149                          + " (pid=" + Binder.getCallingPid()
12150                          + ") when getting content provider " + name);
12151                }
12152            }
12153
12154            boolean checkCrossUser = true;
12155
12156            checkTime(startTime, "getContentProviderImpl: getProviderByName");
12157
12158            // First check if this content provider has been published...
12159            cpr = mProviderMap.getProviderByName(name, userId);
12160            // If that didn't work, check if it exists for user 0 and then
12161            // verify that it's a singleton provider before using it.
12162            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
12163                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
12164                if (cpr != null) {
12165                    cpi = cpr.info;
12166                    if (isSingleton(cpi.processName, cpi.applicationInfo,
12167                            cpi.name, cpi.flags)
12168                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
12169                        userId = UserHandle.USER_SYSTEM;
12170                        checkCrossUser = false;
12171                    } else {
12172                        cpr = null;
12173                        cpi = null;
12174                    }
12175                }
12176            }
12177
12178            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
12179            if (providerRunning) {
12180                cpi = cpr.info;
12181                String msg;
12182                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12183                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
12184                        != null) {
12185                    throw new SecurityException(msg);
12186                }
12187                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
12188
12189                if (r != null && cpr.canRunHere(r)) {
12190                    // This provider has been published or is in the process
12191                    // of being published...  but it is also allowed to run
12192                    // in the caller's process, so don't make a connection
12193                    // and just let the caller instantiate its own instance.
12194                    ContentProviderHolder holder = cpr.newHolder(null);
12195                    // don't give caller the provider object, it needs
12196                    // to make its own.
12197                    holder.provider = null;
12198                    return holder;
12199                }
12200                // Don't expose providers between normal apps and instant apps
12201                try {
12202                    if (AppGlobals.getPackageManager()
12203                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
12204                        return null;
12205                    }
12206                } catch (RemoteException e) {
12207                }
12208
12209                final long origId = Binder.clearCallingIdentity();
12210
12211                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
12212
12213                // In this case the provider instance already exists, so we can
12214                // return it right away.
12215                conn = incProviderCountLocked(r, cpr, token, stable);
12216                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
12217                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12218                        // If this is a perceptible app accessing the provider,
12219                        // make sure to count it as being accessed and thus
12220                        // back up on the LRU list.  This is good because
12221                        // content providers are often expensive to start.
12222                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
12223                        updateLruProcessLocked(cpr.proc, false, null);
12224                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
12225                    }
12226                }
12227
12228                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
12229                final int verifiedAdj = cpr.proc.verifiedAdj;
12230                boolean success = updateOomAdjLocked(cpr.proc, true);
12231                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
12232                // if the process has been successfully adjusted.  So to reduce races with
12233                // it, we will check whether the process still exists.  Note that this doesn't
12234                // completely get rid of races with LMK killing the process, but should make
12235                // them much smaller.
12236                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
12237                    success = false;
12238                }
12239                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
12240                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
12241                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
12242                // NOTE: there is still a race here where a signal could be
12243                // pending on the process even though we managed to update its
12244                // adj level.  Not sure what to do about this, but at least
12245                // the race is now smaller.
12246                if (!success) {
12247                    // Uh oh...  it looks like the provider's process
12248                    // has been killed on us.  We need to wait for a new
12249                    // process to be started, and make sure its death
12250                    // doesn't kill our process.
12251                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
12252                            + " is crashing; detaching " + r);
12253                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
12254                    checkTime(startTime, "getContentProviderImpl: before appDied");
12255                    appDiedLocked(cpr.proc);
12256                    checkTime(startTime, "getContentProviderImpl: after appDied");
12257                    if (!lastRef) {
12258                        // This wasn't the last ref our process had on
12259                        // the provider...  we have now been killed, bail.
12260                        return null;
12261                    }
12262                    providerRunning = false;
12263                    conn = null;
12264                } else {
12265                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
12266                }
12267
12268                Binder.restoreCallingIdentity(origId);
12269            }
12270
12271            if (!providerRunning) {
12272                try {
12273                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
12274                    cpi = AppGlobals.getPackageManager().
12275                        resolveContentProvider(name,
12276                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
12277                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
12278                } catch (RemoteException ex) {
12279                }
12280                if (cpi == null) {
12281                    return null;
12282                }
12283                // If the provider is a singleton AND
12284                // (it's a call within the same user || the provider is a
12285                // privileged app)
12286                // Then allow connecting to the singleton provider
12287                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
12288                        cpi.name, cpi.flags)
12289                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
12290                if (singleton) {
12291                    userId = UserHandle.USER_SYSTEM;
12292                }
12293                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
12294                checkTime(startTime, "getContentProviderImpl: got app info for user");
12295
12296                String msg;
12297                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12298                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
12299                        != null) {
12300                    throw new SecurityException(msg);
12301                }
12302                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
12303
12304                if (!mProcessesReady
12305                        && !cpi.processName.equals("system")) {
12306                    // If this content provider does not run in the system
12307                    // process, and the system is not yet ready to run other
12308                    // processes, then fail fast instead of hanging.
12309                    throw new IllegalArgumentException(
12310                            "Attempt to launch content provider before system ready");
12311                }
12312
12313                // If system providers are not installed yet we aggressively crash to avoid
12314                // creating multiple instance of these providers and then bad things happen!
12315                if (!mSystemProvidersInstalled && cpi.applicationInfo.isSystemApp()
12316                        && "system".equals(cpi.processName)) {
12317                    throw new IllegalStateException("Cannot access system provider: '"
12318                            + cpi.authority + "' before system providers are installed!");
12319                }
12320
12321                // Make sure that the user who owns this provider is running.  If not,
12322                // we don't want to allow it to run.
12323                if (!mUserController.isUserRunning(userId, 0)) {
12324                    Slog.w(TAG, "Unable to launch app "
12325                            + cpi.applicationInfo.packageName + "/"
12326                            + cpi.applicationInfo.uid + " for provider "
12327                            + name + ": user " + userId + " is stopped");
12328                    return null;
12329                }
12330
12331                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
12332                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
12333                cpr = mProviderMap.getProviderByClass(comp, userId);
12334                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
12335                final boolean firstClass = cpr == null;
12336                if (firstClass) {
12337                    final long ident = Binder.clearCallingIdentity();
12338
12339                    // If permissions need a review before any of the app components can run,
12340                    // we return no provider and launch a review activity if the calling app
12341                    // is in the foreground.
12342                    if (mPermissionReviewRequired) {
12343                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
12344                            return null;
12345                        }
12346                    }
12347
12348                    try {
12349                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
12350                        ApplicationInfo ai =
12351                            AppGlobals.getPackageManager().
12352                                getApplicationInfo(
12353                                        cpi.applicationInfo.packageName,
12354                                        STOCK_PM_FLAGS, userId);
12355                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
12356                        if (ai == null) {
12357                            Slog.w(TAG, "No package info for content provider "
12358                                    + cpi.name);
12359                            return null;
12360                        }
12361                        ai = getAppInfoForUser(ai, userId);
12362                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
12363                    } catch (RemoteException ex) {
12364                        // pm is in same process, this will never happen.
12365                    } finally {
12366                        Binder.restoreCallingIdentity(ident);
12367                    }
12368                }
12369
12370                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
12371
12372                if (r != null && cpr.canRunHere(r)) {
12373                    // If this is a multiprocess provider, then just return its
12374                    // info and allow the caller to instantiate it.  Only do
12375                    // this if the provider is the same user as the caller's
12376                    // process, or can run as root (so can be in any process).
12377                    return cpr.newHolder(null);
12378                }
12379
12380                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
12381                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
12382                            + cpr.info.name + " callers=" + Debug.getCallers(6));
12383
12384                // This is single process, and our app is now connecting to it.
12385                // See if we are already in the process of launching this
12386                // provider.
12387                final int N = mLaunchingProviders.size();
12388                int i;
12389                for (i = 0; i < N; i++) {
12390                    if (mLaunchingProviders.get(i) == cpr) {
12391                        break;
12392                    }
12393                }
12394
12395                // If the provider is not already being launched, then get it
12396                // started.
12397                if (i >= N) {
12398                    final long origId = Binder.clearCallingIdentity();
12399
12400                    try {
12401                        // Content provider is now in use, its package can't be stopped.
12402                        try {
12403                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
12404                            AppGlobals.getPackageManager().setPackageStoppedState(
12405                                    cpr.appInfo.packageName, false, userId);
12406                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
12407                        } catch (RemoteException e) {
12408                        } catch (IllegalArgumentException e) {
12409                            Slog.w(TAG, "Failed trying to unstop package "
12410                                    + cpr.appInfo.packageName + ": " + e);
12411                        }
12412
12413                        // Use existing process if already started
12414                        checkTime(startTime, "getContentProviderImpl: looking for process record");
12415                        ProcessRecord proc = getProcessRecordLocked(
12416                                cpi.processName, cpr.appInfo.uid, false);
12417                        if (proc != null && proc.thread != null && !proc.killed) {
12418                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
12419                                    "Installing in existing process " + proc);
12420                            if (!proc.pubProviders.containsKey(cpi.name)) {
12421                                checkTime(startTime, "getContentProviderImpl: scheduling install");
12422                                proc.pubProviders.put(cpi.name, cpr);
12423                                try {
12424                                    proc.thread.scheduleInstallProvider(cpi);
12425                                } catch (RemoteException e) {
12426                                }
12427                            }
12428                        } else {
12429                            checkTime(startTime, "getContentProviderImpl: before start process");
12430                            proc = startProcessLocked(cpi.processName,
12431                                    cpr.appInfo, false, 0, "content provider",
12432                                    new ComponentName(cpi.applicationInfo.packageName,
12433                                            cpi.name), false, false, false);
12434                            checkTime(startTime, "getContentProviderImpl: after start process");
12435                            if (proc == null) {
12436                                Slog.w(TAG, "Unable to launch app "
12437                                        + cpi.applicationInfo.packageName + "/"
12438                                        + cpi.applicationInfo.uid + " for provider "
12439                                        + name + ": process is bad");
12440                                return null;
12441                            }
12442                        }
12443                        cpr.launchingApp = proc;
12444                        mLaunchingProviders.add(cpr);
12445                    } finally {
12446                        Binder.restoreCallingIdentity(origId);
12447                    }
12448                }
12449
12450                checkTime(startTime, "getContentProviderImpl: updating data structures");
12451
12452                // Make sure the provider is published (the same provider class
12453                // may be published under multiple names).
12454                if (firstClass) {
12455                    mProviderMap.putProviderByClass(comp, cpr);
12456                }
12457
12458                mProviderMap.putProviderByName(name, cpr);
12459                conn = incProviderCountLocked(r, cpr, token, stable);
12460                if (conn != null) {
12461                    conn.waiting = true;
12462                }
12463            }
12464            checkTime(startTime, "getContentProviderImpl: done!");
12465
12466            grantEphemeralAccessLocked(userId, null /*intent*/,
12467                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
12468        }
12469
12470        // Wait for the provider to be published...
12471        synchronized (cpr) {
12472            while (cpr.provider == null) {
12473                if (cpr.launchingApp == null) {
12474                    Slog.w(TAG, "Unable to launch app "
12475                            + cpi.applicationInfo.packageName + "/"
12476                            + cpi.applicationInfo.uid + " for provider "
12477                            + name + ": launching app became null");
12478                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
12479                            UserHandle.getUserId(cpi.applicationInfo.uid),
12480                            cpi.applicationInfo.packageName,
12481                            cpi.applicationInfo.uid, name);
12482                    return null;
12483                }
12484                try {
12485                    if (DEBUG_MU) Slog.v(TAG_MU,
12486                            "Waiting to start provider " + cpr
12487                            + " launchingApp=" + cpr.launchingApp);
12488                    if (conn != null) {
12489                        conn.waiting = true;
12490                    }
12491                    cpr.wait();
12492                } catch (InterruptedException ex) {
12493                } finally {
12494                    if (conn != null) {
12495                        conn.waiting = false;
12496                    }
12497                }
12498            }
12499        }
12500        return cpr != null ? cpr.newHolder(conn) : null;
12501    }
12502
12503    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
12504            ProcessRecord r, final int userId) {
12505        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
12506                cpi.packageName, userId)) {
12507
12508            final boolean callerForeground = r == null || r.setSchedGroup
12509                    != ProcessList.SCHED_GROUP_BACKGROUND;
12510
12511            // Show a permission review UI only for starting from a foreground app
12512            if (!callerForeground) {
12513                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
12514                        + cpi.packageName + " requires a permissions review");
12515                return false;
12516            }
12517
12518            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
12519            intent.addFlags(FLAG_ACTIVITY_NEW_TASK
12520                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
12521            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
12522
12523            if (DEBUG_PERMISSIONS_REVIEW) {
12524                Slog.i(TAG, "u" + userId + " Launching permission review "
12525                        + "for package " + cpi.packageName);
12526            }
12527
12528            final UserHandle userHandle = new UserHandle(userId);
12529            mHandler.post(new Runnable() {
12530                @Override
12531                public void run() {
12532                    mContext.startActivityAsUser(intent, userHandle);
12533                }
12534            });
12535
12536            return false;
12537        }
12538
12539        return true;
12540    }
12541
12542    /**
12543     * Returns the PackageManager. Used by classes hosted by {@link ActivityManagerService}. The
12544     * PackageManager could be unavailable at construction time and therefore needs to be accessed
12545     * on demand.
12546     */
12547    IPackageManager getPackageManager() {
12548        return AppGlobals.getPackageManager();
12549    }
12550
12551    ActivityStartController getActivityStartController() {
12552        return mActivityStartController;
12553    }
12554
12555    LockTaskController getLockTaskController() {
12556        return mLockTaskController;
12557    }
12558
12559    ClientLifecycleManager getLifecycleManager() {
12560        return mLifecycleManager;
12561    }
12562
12563    PackageManagerInternal getPackageManagerInternalLocked() {
12564        if (mPackageManagerInt == null) {
12565            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
12566        }
12567        return mPackageManagerInt;
12568    }
12569
12570    @Override
12571    public final ContentProviderHolder getContentProvider(
12572            IApplicationThread caller, String name, int userId, boolean stable) {
12573        enforceNotIsolatedCaller("getContentProvider");
12574        if (caller == null) {
12575            String msg = "null IApplicationThread when getting content provider "
12576                    + name;
12577            Slog.w(TAG, msg);
12578            throw new SecurityException(msg);
12579        }
12580        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
12581        // with cross-user grant.
12582        return getContentProviderImpl(caller, name, null, stable, userId);
12583    }
12584
12585    public ContentProviderHolder getContentProviderExternal(
12586            String name, int userId, IBinder token) {
12587        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12588            "Do not have permission in call getContentProviderExternal()");
12589        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12590                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
12591        return getContentProviderExternalUnchecked(name, token, userId);
12592    }
12593
12594    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
12595            IBinder token, int userId) {
12596        return getContentProviderImpl(null, name, token, true, userId);
12597    }
12598
12599    /**
12600     * Drop a content provider from a ProcessRecord's bookkeeping
12601     */
12602    public void removeContentProvider(IBinder connection, boolean stable) {
12603        enforceNotIsolatedCaller("removeContentProvider");
12604        long ident = Binder.clearCallingIdentity();
12605        try {
12606            synchronized (this) {
12607                ContentProviderConnection conn;
12608                try {
12609                    conn = (ContentProviderConnection)connection;
12610                } catch (ClassCastException e) {
12611                    String msg ="removeContentProvider: " + connection
12612                            + " not a ContentProviderConnection";
12613                    Slog.w(TAG, msg);
12614                    throw new IllegalArgumentException(msg);
12615                }
12616                if (conn == null) {
12617                    throw new NullPointerException("connection is null");
12618                }
12619                if (decProviderCountLocked(conn, null, null, stable)) {
12620                    updateOomAdjLocked();
12621                }
12622            }
12623        } finally {
12624            Binder.restoreCallingIdentity(ident);
12625        }
12626    }
12627
12628    public void removeContentProviderExternal(String name, IBinder token) {
12629        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12630            "Do not have permission in call removeContentProviderExternal()");
12631        int userId = UserHandle.getCallingUserId();
12632        long ident = Binder.clearCallingIdentity();
12633        try {
12634            removeContentProviderExternalUnchecked(name, token, userId);
12635        } finally {
12636            Binder.restoreCallingIdentity(ident);
12637        }
12638    }
12639
12640    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
12641        synchronized (this) {
12642            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
12643            if(cpr == null) {
12644                //remove from mProvidersByClass
12645                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
12646                return;
12647            }
12648
12649            //update content provider record entry info
12650            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
12651            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
12652            if (localCpr.hasExternalProcessHandles()) {
12653                if (localCpr.removeExternalProcessHandleLocked(token)) {
12654                    updateOomAdjLocked();
12655                } else {
12656                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
12657                            + " with no external reference for token: "
12658                            + token + ".");
12659                }
12660            } else {
12661                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
12662                        + " with no external references.");
12663            }
12664        }
12665    }
12666
12667    public final void publishContentProviders(IApplicationThread caller,
12668            List<ContentProviderHolder> providers) {
12669        if (providers == null) {
12670            return;
12671        }
12672
12673        enforceNotIsolatedCaller("publishContentProviders");
12674        synchronized (this) {
12675            final ProcessRecord r = getRecordForAppLocked(caller);
12676            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
12677            if (r == null) {
12678                throw new SecurityException(
12679                        "Unable to find app for caller " + caller
12680                      + " (pid=" + Binder.getCallingPid()
12681                      + ") when publishing content providers");
12682            }
12683
12684            final long origId = Binder.clearCallingIdentity();
12685
12686            final int N = providers.size();
12687            for (int i = 0; i < N; i++) {
12688                ContentProviderHolder src = providers.get(i);
12689                if (src == null || src.info == null || src.provider == null) {
12690                    continue;
12691                }
12692                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
12693                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
12694                if (dst != null) {
12695                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
12696                    mProviderMap.putProviderByClass(comp, dst);
12697                    String names[] = dst.info.authority.split(";");
12698                    for (int j = 0; j < names.length; j++) {
12699                        mProviderMap.putProviderByName(names[j], dst);
12700                    }
12701
12702                    int launchingCount = mLaunchingProviders.size();
12703                    int j;
12704                    boolean wasInLaunchingProviders = false;
12705                    for (j = 0; j < launchingCount; j++) {
12706                        if (mLaunchingProviders.get(j) == dst) {
12707                            mLaunchingProviders.remove(j);
12708                            wasInLaunchingProviders = true;
12709                            j--;
12710                            launchingCount--;
12711                        }
12712                    }
12713                    if (wasInLaunchingProviders) {
12714                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12715                    }
12716                    synchronized (dst) {
12717                        dst.provider = src.provider;
12718                        dst.proc = r;
12719                        dst.notifyAll();
12720                    }
12721                    updateOomAdjLocked(r, true);
12722                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12723                            src.info.authority);
12724                }
12725            }
12726
12727            Binder.restoreCallingIdentity(origId);
12728        }
12729    }
12730
12731    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12732        ContentProviderConnection conn;
12733        try {
12734            conn = (ContentProviderConnection)connection;
12735        } catch (ClassCastException e) {
12736            String msg ="refContentProvider: " + connection
12737                    + " not a ContentProviderConnection";
12738            Slog.w(TAG, msg);
12739            throw new IllegalArgumentException(msg);
12740        }
12741        if (conn == null) {
12742            throw new NullPointerException("connection is null");
12743        }
12744
12745        synchronized (this) {
12746            if (stable > 0) {
12747                conn.numStableIncs += stable;
12748            }
12749            stable = conn.stableCount + stable;
12750            if (stable < 0) {
12751                throw new IllegalStateException("stableCount < 0: " + stable);
12752            }
12753
12754            if (unstable > 0) {
12755                conn.numUnstableIncs += unstable;
12756            }
12757            unstable = conn.unstableCount + unstable;
12758            if (unstable < 0) {
12759                throw new IllegalStateException("unstableCount < 0: " + unstable);
12760            }
12761
12762            if ((stable+unstable) <= 0) {
12763                throw new IllegalStateException("ref counts can't go to zero here: stable="
12764                        + stable + " unstable=" + unstable);
12765            }
12766            conn.stableCount = stable;
12767            conn.unstableCount = unstable;
12768            return !conn.dead;
12769        }
12770    }
12771
12772    public void unstableProviderDied(IBinder connection) {
12773        ContentProviderConnection conn;
12774        try {
12775            conn = (ContentProviderConnection)connection;
12776        } catch (ClassCastException e) {
12777            String msg ="refContentProvider: " + connection
12778                    + " not a ContentProviderConnection";
12779            Slog.w(TAG, msg);
12780            throw new IllegalArgumentException(msg);
12781        }
12782        if (conn == null) {
12783            throw new NullPointerException("connection is null");
12784        }
12785
12786        // Safely retrieve the content provider associated with the connection.
12787        IContentProvider provider;
12788        synchronized (this) {
12789            provider = conn.provider.provider;
12790        }
12791
12792        if (provider == null) {
12793            // Um, yeah, we're way ahead of you.
12794            return;
12795        }
12796
12797        // Make sure the caller is being honest with us.
12798        if (provider.asBinder().pingBinder()) {
12799            // Er, no, still looks good to us.
12800            synchronized (this) {
12801                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12802                        + " says " + conn + " died, but we don't agree");
12803                return;
12804            }
12805        }
12806
12807        // Well look at that!  It's dead!
12808        synchronized (this) {
12809            if (conn.provider.provider != provider) {
12810                // But something changed...  good enough.
12811                return;
12812            }
12813
12814            ProcessRecord proc = conn.provider.proc;
12815            if (proc == null || proc.thread == null) {
12816                // Seems like the process is already cleaned up.
12817                return;
12818            }
12819
12820            // As far as we're concerned, this is just like receiving a
12821            // death notification...  just a bit prematurely.
12822            reportUidInfoMessageLocked(TAG,
12823                    "Process " + proc.processName + " (pid " + proc.pid
12824                            + ") early provider death",
12825                    proc.info.uid);
12826            final long ident = Binder.clearCallingIdentity();
12827            try {
12828                appDiedLocked(proc);
12829            } finally {
12830                Binder.restoreCallingIdentity(ident);
12831            }
12832        }
12833    }
12834
12835    @Override
12836    public void appNotRespondingViaProvider(IBinder connection) {
12837        enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
12838
12839        final ContentProviderConnection conn = (ContentProviderConnection) connection;
12840        if (conn == null) {
12841            Slog.w(TAG, "ContentProviderConnection is null");
12842            return;
12843        }
12844
12845        final ProcessRecord host = conn.provider.proc;
12846        if (host == null) {
12847            Slog.w(TAG, "Failed to find hosting ProcessRecord");
12848            return;
12849        }
12850
12851        mHandler.post(new Runnable() {
12852            @Override
12853            public void run() {
12854                mAppErrors.appNotResponding(host, null, null, false,
12855                        "ContentProvider not responding");
12856            }
12857        });
12858    }
12859
12860    public final void installSystemProviders() {
12861        List<ProviderInfo> providers;
12862        synchronized (this) {
12863            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12864            providers = generateApplicationProvidersLocked(app);
12865            if (providers != null) {
12866                for (int i=providers.size()-1; i>=0; i--) {
12867                    ProviderInfo pi = (ProviderInfo)providers.get(i);
12868                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12869                        Slog.w(TAG, "Not installing system proc provider " + pi.name
12870                                + ": not system .apk");
12871                        providers.remove(i);
12872                    }
12873                }
12874            }
12875        }
12876        if (providers != null) {
12877            mSystemThread.installSystemProviders(providers);
12878        }
12879
12880        synchronized (this) {
12881            mSystemProvidersInstalled = true;
12882        }
12883
12884        mConstants.start(mContext.getContentResolver());
12885        mCoreSettingsObserver = new CoreSettingsObserver(this);
12886        mFontScaleSettingObserver = new FontScaleSettingObserver();
12887        mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
12888        GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
12889
12890        // Now that the settings provider is published we can consider sending
12891        // in a rescue party.
12892        RescueParty.onSettingsProviderPublished(mContext);
12893
12894        //mUsageStatsService.monitorPackages();
12895    }
12896
12897    void startPersistentApps(int matchFlags) {
12898        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12899
12900        synchronized (this) {
12901            try {
12902                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12903                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12904                for (ApplicationInfo app : apps) {
12905                    if (!"android".equals(app.packageName)) {
12906                        addAppLocked(app, null, false, null /* ABI override */);
12907                    }
12908                }
12909            } catch (RemoteException ex) {
12910            }
12911        }
12912    }
12913
12914    /**
12915     * When a user is unlocked, we need to install encryption-unaware providers
12916     * belonging to any running apps.
12917     */
12918    void installEncryptionUnawareProviders(int userId) {
12919        // We're only interested in providers that are encryption unaware, and
12920        // we don't care about uninstalled apps, since there's no way they're
12921        // running at this point.
12922        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12923
12924        synchronized (this) {
12925            final int NP = mProcessNames.getMap().size();
12926            for (int ip = 0; ip < NP; ip++) {
12927                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12928                final int NA = apps.size();
12929                for (int ia = 0; ia < NA; ia++) {
12930                    final ProcessRecord app = apps.valueAt(ia);
12931                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12932
12933                    final int NG = app.pkgList.size();
12934                    for (int ig = 0; ig < NG; ig++) {
12935                        try {
12936                            final String pkgName = app.pkgList.keyAt(ig);
12937                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12938                                    .getPackageInfo(pkgName, matchFlags, userId);
12939                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12940                                for (ProviderInfo pi : pkgInfo.providers) {
12941                                    // TODO: keep in sync with generateApplicationProvidersLocked
12942                                    final boolean processMatch = Objects.equals(pi.processName,
12943                                            app.processName) || pi.multiprocess;
12944                                    final boolean userMatch = isSingleton(pi.processName,
12945                                            pi.applicationInfo, pi.name, pi.flags)
12946                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12947                                    if (processMatch && userMatch) {
12948                                        Log.v(TAG, "Installing " + pi);
12949                                        app.thread.scheduleInstallProvider(pi);
12950                                    } else {
12951                                        Log.v(TAG, "Skipping " + pi);
12952                                    }
12953                                }
12954                            }
12955                        } catch (RemoteException ignored) {
12956                        }
12957                    }
12958                }
12959            }
12960        }
12961    }
12962
12963    /**
12964     * Allows apps to retrieve the MIME type of a URI.
12965     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12966     * users, then it does not need permission to access the ContentProvider.
12967     * Either, it needs cross-user uri grants.
12968     *
12969     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12970     *
12971     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12972     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12973     */
12974    public String getProviderMimeType(Uri uri, int userId) {
12975        enforceNotIsolatedCaller("getProviderMimeType");
12976        final String name = uri.getAuthority();
12977        int callingUid = Binder.getCallingUid();
12978        int callingPid = Binder.getCallingPid();
12979        long ident = 0;
12980        boolean clearedIdentity = false;
12981        userId = mUserController.unsafeConvertIncomingUser(userId);
12982        if (canClearIdentity(callingPid, callingUid, userId)) {
12983            clearedIdentity = true;
12984            ident = Binder.clearCallingIdentity();
12985        }
12986        ContentProviderHolder holder = null;
12987        try {
12988            holder = getContentProviderExternalUnchecked(name, null, userId);
12989            if (holder != null) {
12990                return holder.provider.getType(uri);
12991            }
12992        } catch (RemoteException e) {
12993            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12994            return null;
12995        } catch (Exception e) {
12996            Log.w(TAG, "Exception while determining type of " + uri, e);
12997            return null;
12998        } finally {
12999            // We need to clear the identity to call removeContentProviderExternalUnchecked
13000            if (!clearedIdentity) {
13001                ident = Binder.clearCallingIdentity();
13002            }
13003            try {
13004                if (holder != null) {
13005                    removeContentProviderExternalUnchecked(name, null, userId);
13006                }
13007            } finally {
13008                Binder.restoreCallingIdentity(ident);
13009            }
13010        }
13011
13012        return null;
13013    }
13014
13015    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
13016        if (UserHandle.getUserId(callingUid) == userId) {
13017            return true;
13018        }
13019        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13020                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
13021                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13022                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13023                return true;
13024        }
13025        return false;
13026    }
13027
13028    // =========================================================
13029    // GLOBAL MANAGEMENT
13030    // =========================================================
13031
13032    @GuardedBy("this")
13033    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
13034            boolean isolated, int isolatedUid) {
13035        String proc = customProcess != null ? customProcess : info.processName;
13036        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13037        final int userId = UserHandle.getUserId(info.uid);
13038        int uid = info.uid;
13039        if (isolated) {
13040            if (isolatedUid == 0) {
13041                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
13042                while (true) {
13043                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
13044                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
13045                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
13046                    }
13047                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
13048                    mNextIsolatedProcessUid++;
13049                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
13050                        // No process for this uid, use it.
13051                        break;
13052                    }
13053                    stepsLeft--;
13054                    if (stepsLeft <= 0) {
13055                        return null;
13056                    }
13057                }
13058            } else {
13059                // Special case for startIsolatedProcess (internal only), where
13060                // the uid of the isolated process is specified by the caller.
13061                uid = isolatedUid;
13062            }
13063            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
13064
13065            // Register the isolated UID with this application so BatteryStats knows to
13066            // attribute resource usage to the application.
13067            //
13068            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
13069            // about the process state of the isolated UID *before* it is registered with the
13070            // owning application.
13071            mBatteryStatsService.addIsolatedUid(uid, info.uid);
13072        }
13073        final ProcessRecord r = new ProcessRecord(this, stats, info, proc, uid);
13074        if (!mBooted && !mBooting
13075                && userId == UserHandle.USER_SYSTEM
13076                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
13077            // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
13078            r.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
13079            r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
13080            r.persistent = true;
13081            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
13082        }
13083        if (isolated && isolatedUid != 0) {
13084            // Special case for startIsolatedProcess (internal only) - assume the process
13085            // is required by the system server to prevent it being killed.
13086            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
13087        }
13088        addProcessNameLocked(r);
13089        return r;
13090    }
13091
13092    private boolean uidOnBackgroundWhitelist(final int uid) {
13093        final int appId = UserHandle.getAppId(uid);
13094        final int[] whitelist = mBackgroundAppIdWhitelist;
13095        final int N = whitelist.length;
13096        for (int i = 0; i < N; i++) {
13097            if (appId == whitelist[i]) {
13098                return true;
13099            }
13100        }
13101        return false;
13102    }
13103
13104    @Override
13105    public boolean isBackgroundRestricted(String packageName) {
13106        final int callingUid = Binder.getCallingUid();
13107        final IPackageManager pm = AppGlobals.getPackageManager();
13108        try {
13109            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
13110                    UserHandle.getUserId(callingUid));
13111            if (packageUid != callingUid) {
13112                throw new IllegalArgumentException("Uid " + callingUid
13113                        + " cannot query restriction state for package " + packageName);
13114            }
13115        } catch (RemoteException exc) {
13116            // Ignore.
13117        }
13118        return isBackgroundRestrictedNoCheck(callingUid, packageName);
13119    }
13120
13121    boolean isBackgroundRestrictedNoCheck(final int uid, final String packageName) {
13122        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
13123                uid, packageName);
13124        return mode != AppOpsManager.MODE_ALLOWED;
13125    }
13126
13127    @Override
13128    public void backgroundWhitelistUid(final int uid) {
13129        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13130            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
13131        }
13132
13133        if (DEBUG_BACKGROUND_CHECK) {
13134            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
13135        }
13136        synchronized (this) {
13137            final int N = mBackgroundAppIdWhitelist.length;
13138            int[] newList = new int[N+1];
13139            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
13140            newList[N] = UserHandle.getAppId(uid);
13141            mBackgroundAppIdWhitelist = newList;
13142        }
13143    }
13144
13145    @GuardedBy("this")
13146    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
13147            String abiOverride) {
13148        return addAppLocked(info, customProcess, isolated, false /* disableHiddenApiChecks */,
13149                abiOverride);
13150    }
13151
13152    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
13153            boolean disableHiddenApiChecks, String abiOverride) {
13154        ProcessRecord app;
13155        if (!isolated) {
13156            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
13157                    info.uid, true);
13158        } else {
13159            app = null;
13160        }
13161
13162        if (app == null) {
13163            app = newProcessRecordLocked(info, customProcess, isolated, 0);
13164            updateLruProcessLocked(app, false, null);
13165            updateOomAdjLocked();
13166        }
13167
13168        // This package really, really can not be stopped.
13169        try {
13170            AppGlobals.getPackageManager().setPackageStoppedState(
13171                    info.packageName, false, UserHandle.getUserId(app.uid));
13172        } catch (RemoteException e) {
13173        } catch (IllegalArgumentException e) {
13174            Slog.w(TAG, "Failed trying to unstop package "
13175                    + info.packageName + ": " + e);
13176        }
13177
13178        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
13179            app.persistent = true;
13180            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
13181        }
13182        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
13183            mPersistentStartingProcesses.add(app);
13184            startProcessLocked(app, "added application",
13185                    customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
13186                    abiOverride);
13187        }
13188
13189        return app;
13190    }
13191
13192    public void unhandledBack() {
13193        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
13194                "unhandledBack()");
13195
13196        synchronized(this) {
13197            final long origId = Binder.clearCallingIdentity();
13198            try {
13199                getFocusedStack().unhandledBackLocked();
13200            } finally {
13201                Binder.restoreCallingIdentity(origId);
13202            }
13203        }
13204    }
13205
13206    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
13207        enforceNotIsolatedCaller("openContentUri");
13208        final int userId = UserHandle.getCallingUserId();
13209        final Uri uri = Uri.parse(uriString);
13210        String name = uri.getAuthority();
13211        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
13212        ParcelFileDescriptor pfd = null;
13213        if (cph != null) {
13214            // We record the binder invoker's uid in thread-local storage before
13215            // going to the content provider to open the file.  Later, in the code
13216            // that handles all permissions checks, we look for this uid and use
13217            // that rather than the Activity Manager's own uid.  The effect is that
13218            // we do the check against the caller's permissions even though it looks
13219            // to the content provider like the Activity Manager itself is making
13220            // the request.
13221            Binder token = new Binder();
13222            sCallerIdentity.set(new Identity(
13223                    token, Binder.getCallingPid(), Binder.getCallingUid()));
13224            try {
13225                pfd = cph.provider.openFile(null, uri, "r", null, token);
13226            } catch (FileNotFoundException e) {
13227                // do nothing; pfd will be returned null
13228            } finally {
13229                // Ensure that whatever happens, we clean up the identity state
13230                sCallerIdentity.remove();
13231                // Ensure we're done with the provider.
13232                removeContentProviderExternalUnchecked(name, null, userId);
13233            }
13234        } else {
13235            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
13236        }
13237        return pfd;
13238    }
13239
13240    // Actually is sleeping or shutting down or whatever else in the future
13241    // is an inactive state.
13242    boolean isSleepingOrShuttingDownLocked() {
13243        return isSleepingLocked() || mShuttingDown;
13244    }
13245
13246    boolean isShuttingDownLocked() {
13247        return mShuttingDown;
13248    }
13249
13250    boolean isSleepingLocked() {
13251        return mSleeping;
13252    }
13253
13254    void reportGlobalUsageEventLocked(int event) {
13255        mUsageStatsService.reportEvent("android", mUserController.getCurrentUserId(), event);
13256        int[] profiles = mUserController.getCurrentProfileIds();
13257        if (profiles != null) {
13258            for (int i = profiles.length - 1; i >= 0; i--) {
13259                mUsageStatsService.reportEvent((String)null, profiles[i], event);
13260            }
13261        }
13262    }
13263
13264    void reportCurWakefulnessUsageEventLocked() {
13265        reportGlobalUsageEventLocked(mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE
13266                ? UsageEvents.Event.SCREEN_INTERACTIVE
13267                : UsageEvents.Event.SCREEN_NON_INTERACTIVE);
13268    }
13269
13270    void reportCurKeyguardUsageEventLocked() {
13271        reportGlobalUsageEventLocked(mKeyguardShown
13272                ? UsageEvents.Event.KEYGUARD_SHOWN
13273                : UsageEvents.Event.KEYGUARD_HIDDEN);
13274    }
13275
13276    void onWakefulnessChanged(int wakefulness) {
13277        synchronized(this) {
13278            boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13279            boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13280            mWakefulness = wakefulness;
13281
13282            if (wasAwake != isAwake) {
13283                // Also update state in a special way for running foreground services UI.
13284                mServices.updateScreenStateLocked(isAwake);
13285                reportCurWakefulnessUsageEventLocked();
13286                mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
13287                        .sendToTarget();
13288            }
13289            updateOomAdjLocked();
13290        }
13291    }
13292
13293    @GuardedBy("this")
13294    void finishRunningVoiceLocked() {
13295        if (mRunningVoice != null) {
13296            mRunningVoice = null;
13297            mVoiceWakeLock.release();
13298            updateSleepIfNeededLocked();
13299        }
13300    }
13301
13302    void startTimeTrackingFocusedActivityLocked() {
13303        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
13304        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
13305            mCurAppTimeTracker.start(resumedActivity.packageName);
13306        }
13307    }
13308
13309    @GuardedBy("this")
13310    void updateSleepIfNeededLocked() {
13311        final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
13312        final boolean wasSleeping = mSleeping;
13313
13314        if (!shouldSleep) {
13315            // If wasSleeping is true, we need to wake up activity manager state from when
13316            // we started sleeping. In either case, we need to apply the sleep tokens, which
13317            // will wake up stacks or put them to sleep as appropriate.
13318            if (wasSleeping) {
13319                mSleeping = false;
13320                startTimeTrackingFocusedActivityLocked();
13321                mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
13322                mStackSupervisor.comeOutOfSleepIfNeededLocked();
13323            }
13324            mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
13325            if (wasSleeping) {
13326                updateOomAdjLocked();
13327            }
13328        } else if (!mSleeping && shouldSleep) {
13329            mSleeping = true;
13330            if (mCurAppTimeTracker != null) {
13331                mCurAppTimeTracker.stop();
13332            }
13333            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
13334            mStackSupervisor.goingToSleepLocked();
13335            updateResumedAppTrace(null /* resumed */);
13336            updateOomAdjLocked();
13337        }
13338    }
13339
13340    /** Pokes the task persister. */
13341    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
13342        mRecentTasks.notifyTaskPersisterLocked(task, flush);
13343    }
13344
13345    /**
13346     * Notifies all listeners when the pinned stack animation starts.
13347     */
13348    @Override
13349    public void notifyPinnedStackAnimationStarted() {
13350        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
13351    }
13352
13353    /**
13354     * Notifies all listeners when the pinned stack animation ends.
13355     */
13356    @Override
13357    public void notifyPinnedStackAnimationEnded() {
13358        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
13359    }
13360
13361    @Override
13362    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
13363        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
13364    }
13365
13366    @Override
13367    public boolean shutdown(int timeout) {
13368        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
13369                != PackageManager.PERMISSION_GRANTED) {
13370            throw new SecurityException("Requires permission "
13371                    + android.Manifest.permission.SHUTDOWN);
13372        }
13373
13374        boolean timedout = false;
13375
13376        synchronized(this) {
13377            mShuttingDown = true;
13378            mStackSupervisor.prepareForShutdownLocked();
13379            updateEventDispatchingLocked();
13380            timedout = mStackSupervisor.shutdownLocked(timeout);
13381        }
13382
13383        mAppOpsService.shutdown();
13384        if (mUsageStatsService != null) {
13385            mUsageStatsService.prepareShutdown();
13386        }
13387        mBatteryStatsService.shutdown();
13388        synchronized (this) {
13389            mProcessStats.shutdownLocked();
13390            notifyTaskPersisterLocked(null, true);
13391        }
13392
13393        return timedout;
13394    }
13395
13396    public final void activitySlept(IBinder token) {
13397        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
13398
13399        final long origId = Binder.clearCallingIdentity();
13400
13401        synchronized (this) {
13402            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13403            if (r != null) {
13404                mStackSupervisor.activitySleptLocked(r);
13405            }
13406        }
13407
13408        Binder.restoreCallingIdentity(origId);
13409    }
13410
13411    @GuardedBy("this")
13412    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
13413        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
13414        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
13415        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
13416            boolean wasRunningVoice = mRunningVoice != null;
13417            mRunningVoice = session;
13418            if (!wasRunningVoice) {
13419                mVoiceWakeLock.acquire();
13420                updateSleepIfNeededLocked();
13421            }
13422        }
13423    }
13424
13425    private void updateEventDispatchingLocked() {
13426        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
13427    }
13428
13429    @Override
13430    public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
13431            int secondaryDisplayShowing) {
13432        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
13433                != PackageManager.PERMISSION_GRANTED) {
13434            throw new SecurityException("Requires permission "
13435                    + android.Manifest.permission.DEVICE_POWER);
13436        }
13437
13438        synchronized(this) {
13439            long ident = Binder.clearCallingIdentity();
13440            if (mKeyguardShown != keyguardShowing) {
13441                mKeyguardShown = keyguardShowing;
13442                reportCurKeyguardUsageEventLocked();
13443            }
13444            try {
13445                mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
13446                        secondaryDisplayShowing);
13447            } finally {
13448                Binder.restoreCallingIdentity(ident);
13449            }
13450        }
13451
13452        mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, keyguardShowing ? 1 : 0, 0)
13453                .sendToTarget();
13454    }
13455
13456    @Override
13457    public void notifyLockedProfile(@UserIdInt int userId) {
13458        try {
13459            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
13460                throw new SecurityException("Only privileged app can call notifyLockedProfile");
13461            }
13462        } catch (RemoteException ex) {
13463            throw new SecurityException("Fail to check is caller a privileged app", ex);
13464        }
13465
13466        synchronized (this) {
13467            final long ident = Binder.clearCallingIdentity();
13468            try {
13469                if (mUserController.shouldConfirmCredentials(userId)) {
13470                    if (mKeyguardController.isKeyguardLocked()) {
13471                        // Showing launcher to avoid user entering credential twice.
13472                        final int currentUserId = mUserController.getCurrentUserId();
13473                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
13474                    }
13475                    mStackSupervisor.lockAllProfileTasks(userId);
13476                }
13477            } finally {
13478                Binder.restoreCallingIdentity(ident);
13479            }
13480        }
13481    }
13482
13483    @Override
13484    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
13485        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
13486        synchronized (this) {
13487            final long ident = Binder.clearCallingIdentity();
13488            try {
13489                intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
13490                        FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
13491                        FLAG_ACTIVITY_TASK_ON_HOME);
13492                ActivityOptions activityOptions = options != null
13493                        ? new ActivityOptions(options)
13494                        : ActivityOptions.makeBasic();
13495                activityOptions.setLaunchTaskId(
13496                        mStackSupervisor.getHomeActivity().getTask().taskId);
13497                mContext.startActivityAsUser(intent, activityOptions.toBundle(),
13498                        UserHandle.CURRENT);
13499            } finally {
13500                Binder.restoreCallingIdentity(ident);
13501            }
13502        }
13503    }
13504
13505    @Override
13506    public void stopAppSwitches() {
13507        enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
13508        synchronized(this) {
13509            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
13510                    + APP_SWITCH_DELAY_TIME;
13511            mDidAppSwitch = false;
13512            mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
13513        }
13514    }
13515
13516    public void resumeAppSwitches() {
13517        enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
13518        synchronized(this) {
13519            // Note that we don't execute any pending app switches... we will
13520            // let those wait until either the timeout, or the next start
13521            // activity request.
13522            mAppSwitchesAllowedTime = 0;
13523        }
13524    }
13525
13526    boolean checkAllowAppSwitchUid(int uid) {
13527        ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
13528        if (types != null) {
13529            for (int i = types.size() - 1; i >= 0; i--) {
13530                if (types.valueAt(i).intValue() == uid) {
13531                    return true;
13532                }
13533            }
13534        }
13535        return false;
13536    }
13537
13538    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
13539            int callingPid, int callingUid, String name) {
13540        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
13541            return true;
13542        }
13543
13544        if (mRecentTasks.isCallerRecents(sourceUid)) {
13545            return true;
13546        }
13547
13548        int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
13549        if (perm == PackageManager.PERMISSION_GRANTED) {
13550            return true;
13551        }
13552        if (checkAllowAppSwitchUid(sourceUid)) {
13553            return true;
13554        }
13555
13556        // If the actual IPC caller is different from the logical source, then
13557        // also see if they are allowed to control app switches.
13558        if (callingUid != -1 && callingUid != sourceUid) {
13559            perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
13560            if (perm == PackageManager.PERMISSION_GRANTED) {
13561                return true;
13562            }
13563            if (checkAllowAppSwitchUid(callingUid)) {
13564                return true;
13565            }
13566        }
13567
13568        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
13569        return false;
13570    }
13571
13572    public void setDebugApp(String packageName, boolean waitForDebugger,
13573            boolean persistent) {
13574        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
13575                "setDebugApp()");
13576
13577        long ident = Binder.clearCallingIdentity();
13578        try {
13579            // Note that this is not really thread safe if there are multiple
13580            // callers into it at the same time, but that's not a situation we
13581            // care about.
13582            if (persistent) {
13583                final ContentResolver resolver = mContext.getContentResolver();
13584                Settings.Global.putString(
13585                    resolver, Settings.Global.DEBUG_APP,
13586                    packageName);
13587                Settings.Global.putInt(
13588                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
13589                    waitForDebugger ? 1 : 0);
13590            }
13591
13592            synchronized (this) {
13593                if (!persistent) {
13594                    mOrigDebugApp = mDebugApp;
13595                    mOrigWaitForDebugger = mWaitForDebugger;
13596                }
13597                mDebugApp = packageName;
13598                mWaitForDebugger = waitForDebugger;
13599                mDebugTransient = !persistent;
13600                if (packageName != null) {
13601                    forceStopPackageLocked(packageName, -1, false, false, true, true,
13602                            false, UserHandle.USER_ALL, "set debug app");
13603                }
13604            }
13605        } finally {
13606            Binder.restoreCallingIdentity(ident);
13607        }
13608    }
13609
13610    /**
13611     * Set or remove an agent to be run whenever an app with the given process name starts.
13612     *
13613     * This method will not check whether the given process name matches a debuggable app. That
13614     * would require scanning all current packages, and a rescan when new packages are installed
13615     * or updated.
13616     *
13617     * Instead, do the check when an application is started and matched to a stored agent.
13618     *
13619     * @param packageName the process name of the app.
13620     * @param agent the agent string to be used, or null to remove any previously set agent.
13621     */
13622    @Override
13623    public void setAgentApp(@NonNull String packageName, @Nullable String agent) {
13624        synchronized (this) {
13625            // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13626            // its own permission.
13627            if (checkCallingPermission(
13628                    android.Manifest.permission.SET_ACTIVITY_WATCHER) !=
13629                        PackageManager.PERMISSION_GRANTED) {
13630                throw new SecurityException(
13631                        "Requires permission " + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13632            }
13633
13634            if (agent == null) {
13635                if (mAppAgentMap != null) {
13636                    mAppAgentMap.remove(packageName);
13637                    if (mAppAgentMap.isEmpty()) {
13638                        mAppAgentMap = null;
13639                    }
13640                }
13641            } else {
13642                if (mAppAgentMap == null) {
13643                    mAppAgentMap = new HashMap<>();
13644                }
13645                if (mAppAgentMap.size() >= 100) {
13646                    // Limit the size of the map, to avoid OOMEs.
13647                    Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName
13648                            + "/" + agent);
13649                    return;
13650                }
13651                mAppAgentMap.put(packageName, agent);
13652            }
13653        }
13654    }
13655
13656    void setTrackAllocationApp(ApplicationInfo app, String processName) {
13657        synchronized (this) {
13658            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13659            if (!isDebuggable) {
13660                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13661                    throw new SecurityException("Process not debuggable: " + app.packageName);
13662                }
13663            }
13664
13665            mTrackAllocationApp = processName;
13666        }
13667    }
13668
13669    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
13670        synchronized (this) {
13671            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13672            if (!isDebuggable) {
13673                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13674                    throw new SecurityException("Process not debuggable: " + app.packageName);
13675                }
13676            }
13677            mProfileApp = processName;
13678
13679            if (mProfilerInfo != null) {
13680                if (mProfilerInfo.profileFd != null) {
13681                    try {
13682                        mProfilerInfo.profileFd.close();
13683                    } catch (IOException e) {
13684                    }
13685                }
13686            }
13687            mProfilerInfo = new ProfilerInfo(profilerInfo);
13688            mProfileType = 0;
13689        }
13690    }
13691
13692    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
13693        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13694        if (!isDebuggable) {
13695            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13696                throw new SecurityException("Process not debuggable: " + app.packageName);
13697            }
13698        }
13699        mNativeDebuggingApp = processName;
13700    }
13701
13702    @Override
13703    public void setAlwaysFinish(boolean enabled) {
13704        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
13705                "setAlwaysFinish()");
13706
13707        long ident = Binder.clearCallingIdentity();
13708        try {
13709            Settings.Global.putInt(
13710                    mContext.getContentResolver(),
13711                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
13712
13713            synchronized (this) {
13714                mAlwaysFinishActivities = enabled;
13715            }
13716        } finally {
13717            Binder.restoreCallingIdentity(ident);
13718        }
13719    }
13720
13721    @Override
13722    public void setActivityController(IActivityController controller, boolean imAMonkey) {
13723        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13724                "setActivityController()");
13725        synchronized (this) {
13726            mController = controller;
13727            mControllerIsAMonkey = imAMonkey;
13728            Watchdog.getInstance().setActivityController(controller);
13729        }
13730    }
13731
13732    @Override
13733    public void setUserIsMonkey(boolean userIsMonkey) {
13734        synchronized (this) {
13735            synchronized (mPidsSelfLocked) {
13736                final int callingPid = Binder.getCallingPid();
13737                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
13738                if (proc == null) {
13739                    throw new SecurityException("Unknown process: " + callingPid);
13740                }
13741                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
13742                    throw new SecurityException("Only an instrumentation process "
13743                            + "with a UiAutomation can call setUserIsMonkey");
13744                }
13745            }
13746            mUserIsMonkey = userIsMonkey;
13747        }
13748    }
13749
13750    @Override
13751    public boolean isUserAMonkey() {
13752        synchronized (this) {
13753            // If there is a controller also implies the user is a monkey.
13754            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
13755        }
13756    }
13757
13758    /**
13759     * @deprecated This method is only used by a few internal components and it will soon be
13760     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13761     * No new code should be calling it.
13762     */
13763    @Deprecated
13764    @Override
13765    public void requestBugReport(int bugreportType) {
13766        String extraOptions = null;
13767        switch (bugreportType) {
13768            case ActivityManager.BUGREPORT_OPTION_FULL:
13769                // Default options.
13770                break;
13771            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
13772                extraOptions = "bugreportplus";
13773                break;
13774            case ActivityManager.BUGREPORT_OPTION_REMOTE:
13775                extraOptions = "bugreportremote";
13776                break;
13777            case ActivityManager.BUGREPORT_OPTION_WEAR:
13778                extraOptions = "bugreportwear";
13779                break;
13780            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
13781                extraOptions = "bugreporttelephony";
13782                break;
13783            case ActivityManager.BUGREPORT_OPTION_WIFI:
13784                extraOptions = "bugreportwifi";
13785                break;
13786            default:
13787                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
13788                        + bugreportType);
13789        }
13790        // Always log caller, even if it does not have permission to dump.
13791        String type = extraOptions == null ? "bugreport" : extraOptions;
13792        Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
13793
13794        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13795        if (extraOptions != null) {
13796            SystemProperties.set("dumpstate.options", extraOptions);
13797        }
13798        SystemProperties.set("ctl.start", "bugreport");
13799    }
13800
13801    /**
13802     * @deprecated This method is only used by a few internal components and it will soon be
13803     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13804     * No new code should be calling it.
13805     */
13806    @Deprecated
13807    private void requestBugReportWithDescription(String shareTitle, String shareDescription,
13808                                                 int bugreportType) {
13809        if (!TextUtils.isEmpty(shareTitle)) {
13810            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13811                String errorStr = "shareTitle should be less than " +
13812                        MAX_BUGREPORT_TITLE_SIZE + " characters";
13813                throw new IllegalArgumentException(errorStr);
13814            } else {
13815                if (!TextUtils.isEmpty(shareDescription)) {
13816                    int length;
13817                    try {
13818                        length = shareDescription.getBytes("UTF-8").length;
13819                    } catch (UnsupportedEncodingException e) {
13820                        String errorStr = "shareDescription: UnsupportedEncodingException";
13821                        throw new IllegalArgumentException(errorStr);
13822                    }
13823                    if (length > SystemProperties.PROP_VALUE_MAX) {
13824                        String errorStr = "shareTitle should be less than " +
13825                                SystemProperties.PROP_VALUE_MAX + " bytes";
13826                        throw new IllegalArgumentException(errorStr);
13827                    } else {
13828                        SystemProperties.set("dumpstate.options.description", shareDescription);
13829                    }
13830                }
13831                SystemProperties.set("dumpstate.options.title", shareTitle);
13832            }
13833        }
13834
13835        Slog.d(TAG, "Bugreport notification title " + shareTitle
13836                + " description " + shareDescription);
13837        requestBugReport(bugreportType);
13838    }
13839
13840    /**
13841     * @deprecated This method is only used by a few internal components and it will soon be
13842     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13843     * No new code should be calling it.
13844     */
13845    @Deprecated
13846    @Override
13847    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13848        requestBugReportWithDescription(shareTitle, shareDescription,
13849                ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13850    }
13851
13852    /**
13853     * @deprecated This method is only used by a few internal components and it will soon be
13854     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13855     * No new code should be calling it.
13856     */
13857    @Deprecated
13858    @Override
13859    public void requestWifiBugReport(String shareTitle, String shareDescription) {
13860        requestBugReportWithDescription(shareTitle, shareDescription,
13861                ActivityManager.BUGREPORT_OPTION_WIFI);
13862    }
13863
13864
13865    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13866        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13867    }
13868
13869    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13870        if (r != null && (r.instr != null || r.usingWrapper)) {
13871            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13872        }
13873        return KEY_DISPATCHING_TIMEOUT;
13874    }
13875
13876    @Override
13877    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13878        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13879                != PackageManager.PERMISSION_GRANTED) {
13880            throw new SecurityException("Requires permission "
13881                    + android.Manifest.permission.FILTER_EVENTS);
13882        }
13883        ProcessRecord proc;
13884        long timeout;
13885        synchronized (this) {
13886            synchronized (mPidsSelfLocked) {
13887                proc = mPidsSelfLocked.get(pid);
13888            }
13889            timeout = getInputDispatchingTimeoutLocked(proc);
13890        }
13891
13892        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13893            return -1;
13894        }
13895
13896        return timeout;
13897    }
13898
13899    /**
13900     * Handle input dispatching timeouts.
13901     * Returns whether input dispatching should be aborted or not.
13902     */
13903    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13904            final ActivityRecord activity, final ActivityRecord parent,
13905            final boolean aboveSystem, String reason) {
13906        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13907                != PackageManager.PERMISSION_GRANTED) {
13908            throw new SecurityException("Requires permission "
13909                    + android.Manifest.permission.FILTER_EVENTS);
13910        }
13911
13912        final String annotation;
13913        if (reason == null) {
13914            annotation = "Input dispatching timed out";
13915        } else {
13916            annotation = "Input dispatching timed out (" + reason + ")";
13917        }
13918
13919        if (proc != null) {
13920            synchronized (this) {
13921                if (proc.debugging) {
13922                    return false;
13923                }
13924
13925                if (proc.instr != null) {
13926                    Bundle info = new Bundle();
13927                    info.putString("shortMsg", "keyDispatchingTimedOut");
13928                    info.putString("longMsg", annotation);
13929                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13930                    return true;
13931                }
13932            }
13933            mHandler.post(new Runnable() {
13934                @Override
13935                public void run() {
13936                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13937                }
13938            });
13939        }
13940
13941        return true;
13942    }
13943
13944    @Override
13945    public Bundle getAssistContextExtras(int requestType) {
13946        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13947                null, null, true /* focused */, true /* newSessionId */,
13948                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13949        if (pae == null) {
13950            return null;
13951        }
13952        synchronized (pae) {
13953            while (!pae.haveResult) {
13954                try {
13955                    pae.wait();
13956                } catch (InterruptedException e) {
13957                }
13958            }
13959        }
13960        synchronized (this) {
13961            buildAssistBundleLocked(pae, pae.result);
13962            mPendingAssistExtras.remove(pae);
13963            mUiHandler.removeCallbacks(pae);
13964        }
13965        return pae.extras;
13966    }
13967
13968    @Override
13969    public boolean isAssistDataAllowedOnCurrentActivity() {
13970        int userId;
13971        synchronized (this) {
13972            final ActivityStack focusedStack = getFocusedStack();
13973            if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
13974                return false;
13975            }
13976
13977            final ActivityRecord activity = focusedStack.getTopActivity();
13978            if (activity == null) {
13979                return false;
13980            }
13981            userId = activity.userId;
13982        }
13983        return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
13984    }
13985
13986    @Override
13987    public boolean showAssistFromActivity(IBinder token, Bundle args) {
13988        long ident = Binder.clearCallingIdentity();
13989        try {
13990            synchronized (this) {
13991                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13992                ActivityRecord top = getFocusedStack().getTopActivity();
13993                if (top != caller) {
13994                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13995                            + " is not current top " + top);
13996                    return false;
13997                }
13998                if (!top.nowVisible) {
13999                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
14000                            + " is not visible");
14001                    return false;
14002                }
14003            }
14004            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
14005                    token);
14006        } finally {
14007            Binder.restoreCallingIdentity(ident);
14008        }
14009    }
14010
14011    @Override
14012    public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
14013            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
14014        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
14015                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
14016                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
14017    }
14018
14019    @Override
14020    public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
14021            IBinder activityToken, int flags) {
14022        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
14023                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
14024                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
14025    }
14026
14027    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
14028            IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
14029            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
14030            int flags) {
14031        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
14032                "enqueueAssistContext()");
14033
14034        synchronized (this) {
14035            ActivityRecord activity = getFocusedStack().getTopActivity();
14036            if (activity == null) {
14037                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
14038                return null;
14039            }
14040            if (activity.app == null || activity.app.thread == null) {
14041                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
14042                return null;
14043            }
14044            if (focused) {
14045                if (activityToken != null) {
14046                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
14047                    if (activity != caller) {
14048                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
14049                                + " is not current top " + activity);
14050                        return null;
14051                    }
14052                }
14053            } else {
14054                activity = ActivityRecord.forTokenLocked(activityToken);
14055                if (activity == null) {
14056                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
14057                            + " couldn't be found");
14058                    return null;
14059                }
14060                if (activity.app == null || activity.app.thread == null) {
14061                    Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
14062                    return null;
14063                }
14064            }
14065
14066            PendingAssistExtras pae;
14067            Bundle extras = new Bundle();
14068            if (args != null) {
14069                extras.putAll(args);
14070            }
14071            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
14072            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
14073
14074            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
14075                    userHandle);
14076            pae.isHome = activity.isActivityTypeHome();
14077
14078            // Increment the sessionId if necessary
14079            if (newSessionId) {
14080                mViSessionId++;
14081            }
14082            try {
14083                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
14084                        mViSessionId, flags);
14085                mPendingAssistExtras.add(pae);
14086                mUiHandler.postDelayed(pae, timeout);
14087            } catch (RemoteException e) {
14088                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
14089                return null;
14090            }
14091            return pae;
14092        }
14093    }
14094
14095    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
14096        IAssistDataReceiver receiver;
14097        synchronized (this) {
14098            mPendingAssistExtras.remove(pae);
14099            receiver = pae.receiver;
14100        }
14101        if (receiver != null) {
14102            // Caller wants result sent back to them.
14103            Bundle sendBundle = new Bundle();
14104            // At least return the receiver extras
14105            sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
14106            try {
14107                pae.receiver.onHandleAssistData(sendBundle);
14108            } catch (RemoteException e) {
14109            }
14110        }
14111    }
14112
14113    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
14114        if (result != null) {
14115            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
14116        }
14117        if (pae.hint != null) {
14118            pae.extras.putBoolean(pae.hint, true);
14119        }
14120    }
14121
14122    /** Called from an app when assist data is ready. */
14123    @Override
14124    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
14125            AssistContent content, Uri referrer) {
14126        PendingAssistExtras pae = (PendingAssistExtras)token;
14127        synchronized (pae) {
14128            pae.result = extras;
14129            pae.structure = structure;
14130            pae.content = content;
14131            if (referrer != null) {
14132                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
14133            }
14134            if (structure != null) {
14135                structure.setHomeActivity(pae.isHome);
14136            }
14137            pae.haveResult = true;
14138            pae.notifyAll();
14139            if (pae.intent == null && pae.receiver == null) {
14140                // Caller is just waiting for the result.
14141                return;
14142            }
14143        }
14144        // We are now ready to launch the assist activity.
14145        IAssistDataReceiver sendReceiver = null;
14146        Bundle sendBundle = null;
14147        synchronized (this) {
14148            buildAssistBundleLocked(pae, extras);
14149            boolean exists = mPendingAssistExtras.remove(pae);
14150            mUiHandler.removeCallbacks(pae);
14151            if (!exists) {
14152                // Timed out.
14153                return;
14154            }
14155
14156            if ((sendReceiver=pae.receiver) != null) {
14157                // Caller wants result sent back to them.
14158                sendBundle = new Bundle();
14159                sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
14160                sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
14161                sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
14162                sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
14163            }
14164        }
14165        if (sendReceiver != null) {
14166            try {
14167                sendReceiver.onHandleAssistData(sendBundle);
14168            } catch (RemoteException e) {
14169            }
14170            return;
14171        }
14172
14173        final long ident = Binder.clearCallingIdentity();
14174        try {
14175            if (TextUtils.equals(pae.intent.getAction(),
14176                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
14177                pae.intent.putExtras(pae.extras);
14178                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
14179            } else {
14180                pae.intent.replaceExtras(pae.extras);
14181                pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
14182                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
14183                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
14184                closeSystemDialogs("assist");
14185
14186                try {
14187                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
14188                } catch (ActivityNotFoundException e) {
14189                    Slog.w(TAG, "No activity to handle assist action.", e);
14190                }
14191            }
14192        } finally {
14193            Binder.restoreCallingIdentity(ident);
14194        }
14195    }
14196
14197    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
14198            Bundle args) {
14199        return enqueueAssistContext(requestType, intent, hint, null, null, null,
14200                true /* focused */, true /* newSessionId */, userHandle, args,
14201                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
14202    }
14203
14204    public void registerProcessObserver(IProcessObserver observer) {
14205        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
14206                "registerProcessObserver()");
14207        synchronized (this) {
14208            mProcessObservers.register(observer);
14209        }
14210    }
14211
14212    @Override
14213    public void unregisterProcessObserver(IProcessObserver observer) {
14214        synchronized (this) {
14215            mProcessObservers.unregister(observer);
14216        }
14217    }
14218
14219    @Override
14220    public int getUidProcessState(int uid, String callingPackage) {
14221        if (!hasUsageStatsPermission(callingPackage)) {
14222            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14223                    "getUidProcessState");
14224        }
14225
14226        synchronized (this) {
14227            UidRecord uidRec = mActiveUids.get(uid);
14228            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
14229        }
14230    }
14231
14232    @Override
14233    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
14234            String callingPackage) {
14235        if (!hasUsageStatsPermission(callingPackage)) {
14236            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14237                    "registerUidObserver");
14238        }
14239        synchronized (this) {
14240            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
14241                    callingPackage, which, cutpoint));
14242        }
14243    }
14244
14245    @Override
14246    public void unregisterUidObserver(IUidObserver observer) {
14247        synchronized (this) {
14248            mUidObservers.unregister(observer);
14249        }
14250    }
14251
14252    @Override
14253    public boolean isUidActive(int uid, String callingPackage) {
14254        if (!hasUsageStatsPermission(callingPackage)) {
14255            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
14256                    "isUidActive");
14257        }
14258        synchronized (this) {
14259            return isUidActiveLocked(uid);
14260        }
14261    }
14262
14263    boolean isUidActiveLocked(int uid) {
14264        final UidRecord uidRecord = mActiveUids.get(uid);
14265        return uidRecord != null && !uidRecord.setIdle;
14266    }
14267
14268    @Override
14269    public boolean convertFromTranslucent(IBinder token) {
14270        final long origId = Binder.clearCallingIdentity();
14271        try {
14272            synchronized (this) {
14273                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14274                if (r == null) {
14275                    return false;
14276                }
14277                final boolean translucentChanged = r.changeWindowTranslucency(true);
14278                if (translucentChanged) {
14279                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14280                }
14281                mWindowManager.setAppFullscreen(token, true);
14282                return translucentChanged;
14283            }
14284        } finally {
14285            Binder.restoreCallingIdentity(origId);
14286        }
14287    }
14288
14289    @Override
14290    public boolean convertToTranslucent(IBinder token, Bundle options) {
14291        SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
14292        final long origId = Binder.clearCallingIdentity();
14293        try {
14294            synchronized (this) {
14295                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14296                if (r == null) {
14297                    return false;
14298                }
14299                final TaskRecord task = r.getTask();
14300                int index = task.mActivities.lastIndexOf(r);
14301                if (index > 0) {
14302                    ActivityRecord under = task.mActivities.get(index - 1);
14303                    under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
14304                }
14305                final boolean translucentChanged = r.changeWindowTranslucency(false);
14306                if (translucentChanged) {
14307                    r.getStack().convertActivityToTranslucent(r);
14308                }
14309                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14310                mWindowManager.setAppFullscreen(token, false);
14311                return translucentChanged;
14312            }
14313        } finally {
14314            Binder.restoreCallingIdentity(origId);
14315        }
14316    }
14317
14318    @Override
14319    public Bundle getActivityOptions(IBinder token) {
14320        final long origId = Binder.clearCallingIdentity();
14321        try {
14322            synchronized (this) {
14323                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14324                if (r != null) {
14325                    final ActivityOptions activityOptions = r.takeOptionsLocked();
14326                    return activityOptions == null ? null : activityOptions.toBundle();
14327                }
14328                return null;
14329            }
14330        } finally {
14331            Binder.restoreCallingIdentity(origId);
14332        }
14333    }
14334
14335    @Override
14336    public void setImmersive(IBinder token, boolean immersive) {
14337        synchronized(this) {
14338            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14339            if (r == null) {
14340                throw new IllegalArgumentException();
14341            }
14342            r.immersive = immersive;
14343
14344            // update associated state if we're frontmost
14345            if (r == mStackSupervisor.getResumedActivityLocked()) {
14346                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
14347                applyUpdateLockStateLocked(r);
14348            }
14349        }
14350    }
14351
14352    @Override
14353    public boolean isImmersive(IBinder token) {
14354        synchronized (this) {
14355            ActivityRecord r = ActivityRecord.isInStackLocked(token);
14356            if (r == null) {
14357                throw new IllegalArgumentException();
14358            }
14359            return r.immersive;
14360        }
14361    }
14362
14363    @Override
14364    public void setVrThread(int tid) {
14365        enforceSystemHasVrFeature();
14366        synchronized (this) {
14367            synchronized (mPidsSelfLocked) {
14368                final int pid = Binder.getCallingPid();
14369                final ProcessRecord proc = mPidsSelfLocked.get(pid);
14370                mVrController.setVrThreadLocked(tid, pid, proc);
14371            }
14372        }
14373    }
14374
14375    @Override
14376    public void setPersistentVrThread(int tid) {
14377        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
14378            final String msg = "Permission Denial: setPersistentVrThread() from pid="
14379                    + Binder.getCallingPid()
14380                    + ", uid=" + Binder.getCallingUid()
14381                    + " requires " + permission.RESTRICTED_VR_ACCESS;
14382            Slog.w(TAG, msg);
14383            throw new SecurityException(msg);
14384        }
14385        enforceSystemHasVrFeature();
14386        synchronized (this) {
14387            synchronized (mPidsSelfLocked) {
14388                final int pid = Binder.getCallingPid();
14389                final ProcessRecord proc = mPidsSelfLocked.get(pid);
14390                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
14391            }
14392        }
14393    }
14394
14395    /**
14396     * Schedule the given thread a normal scheduling priority.
14397     *
14398     * @param tid the tid of the thread to adjust the scheduling of.
14399     * @param suppressLogs {@code true} if any error logging should be disabled.
14400     *
14401     * @return {@code true} if this succeeded.
14402     */
14403    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
14404        try {
14405            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
14406            return true;
14407        } catch (IllegalArgumentException e) {
14408            if (!suppressLogs) {
14409                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14410            }
14411        } catch (SecurityException e) {
14412            if (!suppressLogs) {
14413                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14414            }
14415        }
14416        return false;
14417    }
14418
14419    /**
14420     * Schedule the given thread an FIFO scheduling priority.
14421     *
14422     * @param tid the tid of the thread to adjust the scheduling of.
14423     * @param suppressLogs {@code true} if any error logging should be disabled.
14424     *
14425     * @return {@code true} if this succeeded.
14426     */
14427    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
14428        try {
14429            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
14430            return true;
14431        } catch (IllegalArgumentException e) {
14432            if (!suppressLogs) {
14433                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14434            }
14435        } catch (SecurityException e) {
14436            if (!suppressLogs) {
14437                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14438            }
14439        }
14440        return false;
14441    }
14442
14443    /**
14444     * Check that we have the features required for VR-related API calls, and throw an exception if
14445     * not.
14446     */
14447    private void enforceSystemHasVrFeature() {
14448        if (!mContext.getPackageManager().hasSystemFeature(
14449                PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
14450            throw new UnsupportedOperationException("VR mode not supported on this device!");
14451        }
14452    }
14453
14454    @Override
14455    public void setRenderThread(int tid) {
14456        synchronized (this) {
14457            ProcessRecord proc;
14458            int pid = Binder.getCallingPid();
14459            if (pid == Process.myPid()) {
14460                demoteSystemServerRenderThread(tid);
14461                return;
14462            }
14463            synchronized (mPidsSelfLocked) {
14464                proc = mPidsSelfLocked.get(pid);
14465                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
14466                    // ensure the tid belongs to the process
14467                    if (!isThreadInProcess(pid, tid)) {
14468                        throw new IllegalArgumentException(
14469                            "Render thread does not belong to process");
14470                    }
14471                    proc.renderThreadTid = tid;
14472                    if (DEBUG_OOM_ADJ) {
14473                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
14474                    }
14475                    // promote to FIFO now
14476                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
14477                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
14478                        if (mUseFifoUiScheduling) {
14479                            setThreadScheduler(proc.renderThreadTid,
14480                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
14481                        } else {
14482                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
14483                        }
14484                    }
14485                } else {
14486                    if (DEBUG_OOM_ADJ) {
14487                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
14488                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
14489                               mUseFifoUiScheduling);
14490                    }
14491                }
14492            }
14493        }
14494    }
14495
14496    /**
14497     * We only use RenderThread in system_server to store task snapshots to the disk, which should
14498     * happen in the background. Thus, demote render thread from system_server to a lower priority.
14499     *
14500     * @param tid the tid of the RenderThread
14501     */
14502    private void demoteSystemServerRenderThread(int tid) {
14503        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
14504    }
14505
14506    @Override
14507    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
14508        enforceSystemHasVrFeature();
14509
14510        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14511
14512        ActivityRecord r;
14513        synchronized (this) {
14514            r = ActivityRecord.isInStackLocked(token);
14515        }
14516
14517        if (r == null) {
14518            throw new IllegalArgumentException();
14519        }
14520
14521        int err;
14522        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
14523                VrManagerInternal.NO_ERROR) {
14524            return err;
14525        }
14526
14527        // Clear the binder calling uid since this path may call moveToTask().
14528        final long callingId = Binder.clearCallingIdentity();
14529        try {
14530            synchronized(this) {
14531                r.requestedVrComponent = (enabled) ? packageName : null;
14532
14533                // Update associated state if this activity is currently focused
14534                if (r == mStackSupervisor.getResumedActivityLocked()) {
14535                    applyUpdateVrModeLocked(r);
14536                }
14537                return 0;
14538            }
14539        } finally {
14540            Binder.restoreCallingIdentity(callingId);
14541        }
14542    }
14543
14544    @Override
14545    public boolean isVrModePackageEnabled(ComponentName packageName) {
14546        enforceSystemHasVrFeature();
14547
14548        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14549
14550        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
14551                VrManagerInternal.NO_ERROR;
14552    }
14553
14554    public boolean isTopActivityImmersive() {
14555        enforceNotIsolatedCaller("startActivity");
14556        synchronized (this) {
14557            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
14558            return (r != null) ? r.immersive : false;
14559        }
14560    }
14561
14562    /**
14563     * @return whether the system should disable UI modes incompatible with VR mode.
14564     */
14565    boolean shouldDisableNonVrUiLocked() {
14566        return mVrController.shouldDisableNonVrUiLocked();
14567    }
14568
14569    @Override
14570    public boolean isTopOfTask(IBinder token) {
14571        synchronized (this) {
14572            ActivityRecord r = ActivityRecord.isInStackLocked(token);
14573            if (r == null) {
14574                throw new IllegalArgumentException();
14575            }
14576            return r.getTask().getTopActivity() == r;
14577        }
14578    }
14579
14580    @Override
14581    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
14582        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
14583            String msg = "Permission Denial: setHasTopUi() from pid="
14584                    + Binder.getCallingPid()
14585                    + ", uid=" + Binder.getCallingUid()
14586                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
14587            Slog.w(TAG, msg);
14588            throw new SecurityException(msg);
14589        }
14590        final int pid = Binder.getCallingPid();
14591        final long origId = Binder.clearCallingIdentity();
14592        try {
14593            synchronized (this) {
14594                boolean changed = false;
14595                ProcessRecord pr;
14596                synchronized (mPidsSelfLocked) {
14597                    pr = mPidsSelfLocked.get(pid);
14598                    if (pr == null) {
14599                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
14600                        return;
14601                    }
14602                    if (pr.hasTopUi != hasTopUi) {
14603                        if (DEBUG_OOM_ADJ) {
14604                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
14605                        }
14606                        pr.hasTopUi = hasTopUi;
14607                        changed = true;
14608                    }
14609                }
14610                if (changed) {
14611                    updateOomAdjLocked(pr, true);
14612                }
14613            }
14614        } finally {
14615            Binder.restoreCallingIdentity(origId);
14616        }
14617    }
14618
14619    void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
14620        if (pid == Process.myPid()) {
14621            Slog.wtf(TAG, "system can't run remote animation");
14622            return;
14623        }
14624        synchronized (ActivityManagerService.this) {
14625            final ProcessRecord pr;
14626            synchronized (mPidsSelfLocked) {
14627                pr = mPidsSelfLocked.get(pid);
14628                if (pr == null) {
14629                    Slog.w(TAG, "setRunningRemoteAnimation called on unknown pid: " + pid);
14630                    return;
14631                }
14632            }
14633            if (pr.runningRemoteAnimation == runningRemoteAnimation) {
14634                return;
14635            }
14636            pr.runningRemoteAnimation = runningRemoteAnimation;
14637            if (DEBUG_OOM_ADJ) {
14638                Slog.i(TAG, "Setting runningRemoteAnimation=" + pr.runningRemoteAnimation
14639                        + " for pid=" + pid);
14640            }
14641            updateOomAdjLocked(pr, true);
14642        }
14643    }
14644
14645    public final void enterSafeMode() {
14646        synchronized(this) {
14647            // It only makes sense to do this before the system is ready
14648            // and started launching other packages.
14649            if (!mSystemReady) {
14650                try {
14651                    AppGlobals.getPackageManager().enterSafeMode();
14652                } catch (RemoteException e) {
14653                }
14654            }
14655
14656            mSafeMode = true;
14657        }
14658    }
14659
14660    public final void showSafeModeOverlay() {
14661        View v = LayoutInflater.from(mContext).inflate(
14662                com.android.internal.R.layout.safe_mode, null);
14663        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
14664        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
14665        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
14666        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
14667        lp.gravity = Gravity.BOTTOM | Gravity.START;
14668        lp.format = v.getBackground().getOpacity();
14669        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
14670                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
14671        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
14672        ((WindowManager)mContext.getSystemService(
14673                Context.WINDOW_SERVICE)).addView(v, lp);
14674    }
14675
14676    @Override
14677    public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
14678            String sourcePkg, String tag) {
14679        if (workSource != null && workSource.isEmpty()) {
14680            workSource = null;
14681        }
14682
14683        if (sourceUid <= 0 && workSource == null) {
14684            // Try and derive a UID to attribute things to based on the caller.
14685            if (sender != null) {
14686                if (!(sender instanceof PendingIntentRecord)) {
14687                    return;
14688                }
14689
14690                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14691                final int callerUid = Binder.getCallingUid();
14692                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14693            } else {
14694                // TODO(narayan): Should we throw an exception in this case ? It means that we
14695                // haven't been able to derive a UID to attribute things to.
14696                return;
14697            }
14698        }
14699
14700        if (DEBUG_POWER) {
14701            Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
14702                    + ", workSource=" + workSource + ", tag=" + tag + "]");
14703        }
14704
14705        mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
14706    }
14707
14708    @Override
14709    public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
14710            String tag) {
14711        if (workSource != null && workSource.isEmpty()) {
14712            workSource = null;
14713        }
14714
14715        if (sourceUid <= 0 && workSource == null) {
14716            // Try and derive a UID to attribute things to based on the caller.
14717            if (sender != null) {
14718                if (!(sender instanceof PendingIntentRecord)) {
14719                    return;
14720                }
14721
14722                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14723                final int callerUid = Binder.getCallingUid();
14724                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14725            } else {
14726                // TODO(narayan): Should we throw an exception in this case ? It means that we
14727                // haven't been able to derive a UID to attribute things to.
14728                return;
14729            }
14730        }
14731
14732        if (DEBUG_POWER) {
14733            Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
14734                    ", tag=" + tag + "]");
14735        }
14736
14737        mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
14738    }
14739
14740    @Override
14741    public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
14742            String tag) {
14743        if (workSource != null && workSource.isEmpty()) {
14744            workSource = null;
14745        }
14746
14747        if (sourceUid <= 0 && workSource == null) {
14748            // Try and derive a UID to attribute things to based on the caller.
14749            if (sender != null) {
14750                if (!(sender instanceof PendingIntentRecord)) {
14751                    return;
14752                }
14753
14754                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14755                final int callerUid = Binder.getCallingUid();
14756                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14757            } else {
14758                // TODO(narayan): Should we throw an exception in this case ? It means that we
14759                // haven't been able to derive a UID to attribute things to.
14760                return;
14761            }
14762        }
14763
14764        if (DEBUG_POWER) {
14765            Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
14766                    ", tag=" + tag + "]");
14767        }
14768
14769        mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
14770    }
14771
14772    public boolean killPids(int[] pids, String pReason, boolean secure) {
14773        if (Binder.getCallingUid() != SYSTEM_UID) {
14774            throw new SecurityException("killPids only available to the system");
14775        }
14776        String reason = (pReason == null) ? "Unknown" : pReason;
14777        // XXX Note: don't acquire main activity lock here, because the window
14778        // manager calls in with its locks held.
14779
14780        boolean killed = false;
14781        synchronized (mPidsSelfLocked) {
14782            int worstType = 0;
14783            for (int i=0; i<pids.length; i++) {
14784                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14785                if (proc != null) {
14786                    int type = proc.setAdj;
14787                    if (type > worstType) {
14788                        worstType = type;
14789                    }
14790                }
14791            }
14792
14793            // If the worst oom_adj is somewhere in the cached proc LRU range,
14794            // then constrain it so we will kill all cached procs.
14795            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
14796                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
14797                worstType = ProcessList.CACHED_APP_MIN_ADJ;
14798            }
14799
14800            // If this is not a secure call, don't let it kill processes that
14801            // are important.
14802            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
14803                worstType = ProcessList.SERVICE_ADJ;
14804            }
14805
14806            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
14807            for (int i=0; i<pids.length; i++) {
14808                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14809                if (proc == null) {
14810                    continue;
14811                }
14812                int adj = proc.setAdj;
14813                if (adj >= worstType && !proc.killedByAm) {
14814                    proc.kill(reason, true);
14815                    killed = true;
14816                }
14817            }
14818        }
14819        return killed;
14820    }
14821
14822    @Override
14823    public void killUid(int appId, int userId, String reason) {
14824        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
14825        synchronized (this) {
14826            final long identity = Binder.clearCallingIdentity();
14827            try {
14828                killPackageProcessesLocked(null, appId, userId,
14829                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
14830                        reason != null ? reason : "kill uid");
14831            } finally {
14832                Binder.restoreCallingIdentity(identity);
14833            }
14834        }
14835    }
14836
14837    @Override
14838    public boolean killProcessesBelowForeground(String reason) {
14839        if (Binder.getCallingUid() != SYSTEM_UID) {
14840            throw new SecurityException("killProcessesBelowForeground() only available to system");
14841        }
14842
14843        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
14844    }
14845
14846    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
14847        if (Binder.getCallingUid() != SYSTEM_UID) {
14848            throw new SecurityException("killProcessesBelowAdj() only available to system");
14849        }
14850
14851        boolean killed = false;
14852        synchronized (mPidsSelfLocked) {
14853            final int size = mPidsSelfLocked.size();
14854            for (int i = 0; i < size; i++) {
14855                final int pid = mPidsSelfLocked.keyAt(i);
14856                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14857                if (proc == null) continue;
14858
14859                final int adj = proc.setAdj;
14860                if (adj > belowAdj && !proc.killedByAm) {
14861                    proc.kill(reason, true);
14862                    killed = true;
14863                }
14864            }
14865        }
14866        return killed;
14867    }
14868
14869    @Override
14870    public void hang(final IBinder who, boolean allowRestart) {
14871        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14872                != PackageManager.PERMISSION_GRANTED) {
14873            throw new SecurityException("Requires permission "
14874                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14875        }
14876
14877        final IBinder.DeathRecipient death = new DeathRecipient() {
14878            @Override
14879            public void binderDied() {
14880                synchronized (this) {
14881                    notifyAll();
14882                }
14883            }
14884        };
14885
14886        try {
14887            who.linkToDeath(death, 0);
14888        } catch (RemoteException e) {
14889            Slog.w(TAG, "hang: given caller IBinder is already dead.");
14890            return;
14891        }
14892
14893        synchronized (this) {
14894            Watchdog.getInstance().setAllowRestart(allowRestart);
14895            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
14896            synchronized (death) {
14897                while (who.isBinderAlive()) {
14898                    try {
14899                        death.wait();
14900                    } catch (InterruptedException e) {
14901                    }
14902                }
14903            }
14904            Watchdog.getInstance().setAllowRestart(true);
14905        }
14906    }
14907
14908    @Override
14909    public void restart() {
14910        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14911                != PackageManager.PERMISSION_GRANTED) {
14912            throw new SecurityException("Requires permission "
14913                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14914        }
14915
14916        Log.i(TAG, "Sending shutdown broadcast...");
14917
14918        BroadcastReceiver br = new BroadcastReceiver() {
14919            @Override public void onReceive(Context context, Intent intent) {
14920                // Now the broadcast is done, finish up the low-level shutdown.
14921                Log.i(TAG, "Shutting down activity manager...");
14922                shutdown(10000);
14923                Log.i(TAG, "Shutdown complete, restarting!");
14924                killProcess(myPid());
14925                System.exit(10);
14926            }
14927        };
14928
14929        // First send the high-level shut down broadcast.
14930        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14931        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14932        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
14933        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
14934        mContext.sendOrderedBroadcastAsUser(intent,
14935                UserHandle.ALL, null, br, mHandler, 0, null, null);
14936        */
14937        br.onReceive(mContext, intent);
14938    }
14939
14940    private long getLowRamTimeSinceIdle(long now) {
14941        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
14942    }
14943
14944    @Override
14945    public void performIdleMaintenance() {
14946        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14947                != PackageManager.PERMISSION_GRANTED) {
14948            throw new SecurityException("Requires permission "
14949                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14950        }
14951
14952        synchronized (this) {
14953            final long now = SystemClock.uptimeMillis();
14954            final long timeSinceLastIdle = now - mLastIdleTime;
14955            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
14956            mLastIdleTime = now;
14957            mLowRamTimeSinceLastIdle = 0;
14958            if (mLowRamStartTime != 0) {
14959                mLowRamStartTime = now;
14960            }
14961
14962            StringBuilder sb = new StringBuilder(128);
14963            sb.append("Idle maintenance over ");
14964            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14965            sb.append(" low RAM for ");
14966            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14967            Slog.i(TAG, sb.toString());
14968
14969            // If at least 1/3 of our time since the last idle period has been spent
14970            // with RAM low, then we want to kill processes.
14971            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14972
14973            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14974                ProcessRecord proc = mLruProcesses.get(i);
14975                if (proc.notCachedSinceIdle) {
14976                    if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
14977                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14978                        if (doKilling && proc.initialIdlePss != 0
14979                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14980                            sb = new StringBuilder(128);
14981                            sb.append("Kill");
14982                            sb.append(proc.processName);
14983                            sb.append(" in idle maint: pss=");
14984                            sb.append(proc.lastPss);
14985                            sb.append(", swapPss=");
14986                            sb.append(proc.lastSwapPss);
14987                            sb.append(", initialPss=");
14988                            sb.append(proc.initialIdlePss);
14989                            sb.append(", period=");
14990                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14991                            sb.append(", lowRamPeriod=");
14992                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14993                            Slog.wtfQuiet(TAG, sb.toString());
14994                            proc.kill("idle maint (pss " + proc.lastPss
14995                                    + " from " + proc.initialIdlePss + ")", true);
14996                        }
14997                    }
14998                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14999                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
15000                    proc.notCachedSinceIdle = true;
15001                    proc.initialIdlePss = 0;
15002                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null,
15003                            mTestPssMode, isSleepingLocked(), now);
15004                }
15005            }
15006        }
15007    }
15008
15009    @Override
15010    public void sendIdleJobTrigger() {
15011        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15012                != PackageManager.PERMISSION_GRANTED) {
15013            throw new SecurityException("Requires permission "
15014                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15015        }
15016
15017        final long ident = Binder.clearCallingIdentity();
15018        try {
15019            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
15020                    .setPackage("android")
15021                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15022            broadcastIntent(null, intent, null, null, 0, null, null, null,
15023                    OP_NONE, null, false, false, UserHandle.USER_ALL);
15024        } finally {
15025            Binder.restoreCallingIdentity(ident);
15026        }
15027    }
15028
15029    private void retrieveSettings() {
15030        final ContentResolver resolver = mContext.getContentResolver();
15031        final boolean freeformWindowManagement =
15032                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
15033                        || Settings.Global.getInt(
15034                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
15035
15036        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
15037        final boolean supportsPictureInPicture = supportsMultiWindow &&
15038                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
15039        final boolean supportsSplitScreenMultiWindow =
15040                ActivityManager.supportsSplitScreenMultiWindow(mContext);
15041        final boolean supportsMultiDisplay = mContext.getPackageManager()
15042                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
15043        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
15044        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
15045        final boolean alwaysFinishActivities =
15046                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
15047        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
15048        final boolean forceResizable = Settings.Global.getInt(
15049                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
15050        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
15051                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
15052        final boolean supportsLeanbackOnly =
15053                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
15054        mHiddenApiBlacklist.registerObserver();
15055
15056        // Transfer any global setting for forcing RTL layout, into a System Property
15057        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
15058
15059        final Configuration configuration = new Configuration();
15060        Settings.System.getConfiguration(resolver, configuration);
15061        if (forceRtl) {
15062            // This will take care of setting the correct layout direction flags
15063            configuration.setLayoutDirection(configuration.locale);
15064        }
15065
15066        synchronized (this) {
15067            mDebugApp = mOrigDebugApp = debugApp;
15068            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
15069            mAlwaysFinishActivities = alwaysFinishActivities;
15070            mSupportsLeanbackOnly = supportsLeanbackOnly;
15071            mForceResizableActivities = forceResizable;
15072            final boolean multiWindowFormEnabled = freeformWindowManagement
15073                    || supportsSplitScreenMultiWindow
15074                    || supportsPictureInPicture
15075                    || supportsMultiDisplay;
15076            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
15077                mSupportsMultiWindow = true;
15078                mSupportsFreeformWindowManagement = freeformWindowManagement;
15079                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
15080                mSupportsPictureInPicture = supportsPictureInPicture;
15081                mSupportsMultiDisplay = supportsMultiDisplay;
15082            } else {
15083                mSupportsMultiWindow = false;
15084                mSupportsFreeformWindowManagement = false;
15085                mSupportsSplitScreenMultiWindow = false;
15086                mSupportsPictureInPicture = false;
15087                mSupportsMultiDisplay = false;
15088            }
15089            mWindowManager.setForceResizableTasks(mForceResizableActivities);
15090            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
15091            // This happens before any activities are started, so we can change global configuration
15092            // in-place.
15093            updateConfigurationLocked(configuration, null, true);
15094            final Configuration globalConfig = getGlobalConfiguration();
15095            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
15096
15097            // Load resources only after the current configuration has been set.
15098            final Resources res = mContext.getResources();
15099            mThumbnailWidth = res.getDimensionPixelSize(
15100                    com.android.internal.R.dimen.thumbnail_width);
15101            mThumbnailHeight = res.getDimensionPixelSize(
15102                    com.android.internal.R.dimen.thumbnail_height);
15103            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
15104                    com.android.internal.R.string.config_appsNotReportingCrashes));
15105            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
15106                    com.android.internal.R.bool.config_customUserSwitchUi);
15107            mUserController.mMaxRunningUsers = res.getInteger(
15108                    com.android.internal.R.integer.config_multiuserMaxRunningUsers);
15109
15110            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
15111                mFullscreenThumbnailScale = (float) res
15112                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
15113                    (float) globalConfig.screenWidthDp;
15114            } else {
15115                mFullscreenThumbnailScale = res.getFraction(
15116                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
15117            }
15118            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
15119        }
15120    }
15121
15122    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
15123        traceLog.traceBegin("PhaseActivityManagerReady");
15124        synchronized(this) {
15125            if (mSystemReady) {
15126                // If we're done calling all the receivers, run the next "boot phase" passed in
15127                // by the SystemServer
15128                if (goingCallback != null) {
15129                    goingCallback.run();
15130                }
15131                return;
15132            }
15133
15134            mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
15135                    PackageManager.FEATURE_CANT_SAVE_STATE);
15136            mLocalDeviceIdleController
15137                    = LocalServices.getService(DeviceIdleController.LocalService.class);
15138            mAssistUtils = new AssistUtils(mContext);
15139            mVrController.onSystemReady();
15140            // Make sure we have the current profile info, since it is needed for security checks.
15141            mUserController.onSystemReady();
15142            mRecentTasks.onSystemReadyLocked();
15143            mAppOpsService.systemReady();
15144            mSystemReady = true;
15145        }
15146
15147        try {
15148            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
15149                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
15150                    .getSerial();
15151        } catch (RemoteException e) {}
15152
15153        ArrayList<ProcessRecord> procsToKill = null;
15154        synchronized(mPidsSelfLocked) {
15155            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
15156                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
15157                if (!isAllowedWhileBooting(proc.info)){
15158                    if (procsToKill == null) {
15159                        procsToKill = new ArrayList<ProcessRecord>();
15160                    }
15161                    procsToKill.add(proc);
15162                }
15163            }
15164        }
15165
15166        synchronized(this) {
15167            if (procsToKill != null) {
15168                for (int i=procsToKill.size()-1; i>=0; i--) {
15169                    ProcessRecord proc = procsToKill.get(i);
15170                    Slog.i(TAG, "Removing system update proc: " + proc);
15171                    removeProcessLocked(proc, true, false, "system update done");
15172                }
15173            }
15174
15175            // Now that we have cleaned up any update processes, we
15176            // are ready to start launching real processes and know that
15177            // we won't trample on them any more.
15178            mProcessesReady = true;
15179        }
15180
15181        Slog.i(TAG, "System now ready");
15182        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
15183            SystemClock.uptimeMillis());
15184
15185        synchronized(this) {
15186            // Make sure we have no pre-ready processes sitting around.
15187
15188            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
15189                ResolveInfo ri = mContext.getPackageManager()
15190                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
15191                                STOCK_PM_FLAGS);
15192                CharSequence errorMsg = null;
15193                if (ri != null) {
15194                    ActivityInfo ai = ri.activityInfo;
15195                    ApplicationInfo app = ai.applicationInfo;
15196                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
15197                        mTopAction = Intent.ACTION_FACTORY_TEST;
15198                        mTopData = null;
15199                        mTopComponent = new ComponentName(app.packageName,
15200                                ai.name);
15201                    } else {
15202                        errorMsg = mContext.getResources().getText(
15203                                com.android.internal.R.string.factorytest_not_system);
15204                    }
15205                } else {
15206                    errorMsg = mContext.getResources().getText(
15207                            com.android.internal.R.string.factorytest_no_action);
15208                }
15209                if (errorMsg != null) {
15210                    mTopAction = null;
15211                    mTopData = null;
15212                    mTopComponent = null;
15213                    Message msg = Message.obtain();
15214                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
15215                    msg.getData().putCharSequence("msg", errorMsg);
15216                    mUiHandler.sendMessage(msg);
15217                }
15218            }
15219        }
15220
15221        retrieveSettings();
15222        final int currentUserId = mUserController.getCurrentUserId();
15223        synchronized (this) {
15224            readGrantedUriPermissionsLocked();
15225        }
15226
15227        final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
15228        if (pmi != null) {
15229            pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
15230                    state -> updateForceBackgroundCheck(state.batterySaverEnabled));
15231            updateForceBackgroundCheck(
15232                    pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
15233        } else {
15234            Slog.wtf(TAG, "PowerManagerInternal not found.");
15235        }
15236
15237        if (goingCallback != null) goingCallback.run();
15238        traceLog.traceBegin("ActivityManagerStartApps");
15239        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
15240                Integer.toString(currentUserId), currentUserId);
15241        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
15242                Integer.toString(currentUserId), currentUserId);
15243        mSystemServiceManager.startUser(currentUserId);
15244
15245        synchronized (this) {
15246            // Only start up encryption-aware persistent apps; once user is
15247            // unlocked we'll come back around and start unaware apps
15248            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
15249
15250            // Start up initial activity.
15251            mBooting = true;
15252            // Enable home activity for system user, so that the system can always boot. We don't
15253            // do this when the system user is not setup since the setup wizard should be the one
15254            // to handle home activity in this case.
15255            if (UserManager.isSplitSystemUser() &&
15256                    Settings.Secure.getInt(mContext.getContentResolver(),
15257                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
15258                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
15259                try {
15260                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
15261                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
15262                            UserHandle.USER_SYSTEM);
15263                } catch (RemoteException e) {
15264                    throw e.rethrowAsRuntimeException();
15265                }
15266            }
15267            startHomeActivityLocked(currentUserId, "systemReady");
15268
15269            try {
15270                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
15271                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
15272                            + " data partition or your device will be unstable.");
15273                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
15274                }
15275            } catch (RemoteException e) {
15276            }
15277
15278            if (!Build.isBuildConsistent()) {
15279                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
15280                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
15281            }
15282
15283            long ident = Binder.clearCallingIdentity();
15284            try {
15285                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
15286                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15287                        | Intent.FLAG_RECEIVER_FOREGROUND);
15288                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
15289                broadcastIntentLocked(null, null, intent,
15290                        null, null, 0, null, null, null, OP_NONE,
15291                        null, false, false, MY_PID, SYSTEM_UID,
15292                        currentUserId);
15293                intent = new Intent(Intent.ACTION_USER_STARTING);
15294                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15295                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
15296                broadcastIntentLocked(null, null, intent,
15297                        null, new IIntentReceiver.Stub() {
15298                            @Override
15299                            public void performReceive(Intent intent, int resultCode, String data,
15300                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
15301                                    throws RemoteException {
15302                            }
15303                        }, 0, null, null,
15304                        new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
15305                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
15306            } catch (Throwable t) {
15307                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
15308            } finally {
15309                Binder.restoreCallingIdentity(ident);
15310            }
15311            mStackSupervisor.resumeFocusedStackTopActivityLocked();
15312            mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
15313
15314            BinderInternal.nSetBinderProxyCountWatermarks(6000,5500);
15315            BinderInternal.nSetBinderProxyCountEnabled(true);
15316            BinderInternal.setBinderProxyCountCallback(
15317                    new BinderInternal.BinderProxyLimitListener() {
15318                        @Override
15319                        public void onLimitReached(int uid) {
15320                            Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
15321                                    + Process.myUid());
15322                            if (uid == Process.SYSTEM_UID) {
15323                                Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
15324                            } else {
15325                                killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
15326                                        "Too many Binders sent to SYSTEM");
15327                            }
15328                        }
15329                    }, mHandler);
15330
15331            traceLog.traceEnd(); // ActivityManagerStartApps
15332            traceLog.traceEnd(); // PhaseActivityManagerReady
15333        }
15334    }
15335
15336    private void updateForceBackgroundCheck(boolean enabled) {
15337        synchronized (this) {
15338            if (mForceBackgroundCheck != enabled) {
15339                mForceBackgroundCheck = enabled;
15340
15341                if (DEBUG_BACKGROUND_CHECK) {
15342                    Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
15343                }
15344
15345                if (mForceBackgroundCheck) {
15346                    // Stop background services for idle UIDs.
15347                    doStopUidForIdleUidsLocked();
15348                }
15349            }
15350        }
15351    }
15352
15353    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
15354        synchronized (this) {
15355            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
15356        }
15357    }
15358
15359    void skipCurrentReceiverLocked(ProcessRecord app) {
15360        for (BroadcastQueue queue : mBroadcastQueues) {
15361            queue.skipCurrentReceiverLocked(app);
15362        }
15363    }
15364
15365    /**
15366     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
15367     * The application process will exit immediately after this call returns.
15368     * @param app object of the crashing app, null for the system server
15369     * @param crashInfo describing the exception
15370     */
15371    public void handleApplicationCrash(IBinder app,
15372            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15373        ProcessRecord r = findAppProcess(app, "Crash");
15374        final String processName = app == null ? "system_server"
15375                : (r == null ? "unknown" : r.processName);
15376
15377        handleApplicationCrashInner("crash", r, processName, crashInfo);
15378    }
15379
15380    /* Native crash reporting uses this inner version because it needs to be somewhat
15381     * decoupled from the AM-managed cleanup lifecycle
15382     */
15383    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
15384            ApplicationErrorReport.CrashInfo crashInfo) {
15385        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
15386                UserHandle.getUserId(Binder.getCallingUid()), processName,
15387                r == null ? -1 : r.info.flags,
15388                crashInfo.exceptionClassName,
15389                crashInfo.exceptionMessage,
15390                crashInfo.throwFileName,
15391                crashInfo.throwLineNumber);
15392
15393        StatsLog.write(StatsLog.APP_CRASH_OCCURRED,
15394                Binder.getCallingUid(),
15395                eventType,
15396                processName,
15397                Binder.getCallingPid(),
15398                (r != null && r.info != null) ? r.info.packageName : "",
15399                (r != null && r.info != null) ? (r.info.isInstantApp()
15400                        ? StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__TRUE
15401                        : StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__FALSE)
15402                        : StatsLog.APP_CRASH_OCCURRED__IS_INSTANT_APP__UNAVAILABLE,
15403                r != null ? (r.isInterestingToUserLocked()
15404                        ? StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__FOREGROUND
15405                        : StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__BACKGROUND)
15406                        : StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__UNKNOWN
15407        );
15408
15409        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
15410
15411        mAppErrors.crashApplication(r, crashInfo);
15412    }
15413
15414    public void handleApplicationStrictModeViolation(
15415            IBinder app,
15416            int violationMask,
15417            StrictMode.ViolationInfo info) {
15418        // We're okay if the ProcessRecord is missing; it probably means that
15419        // we're reporting a violation from the system process itself.
15420        final ProcessRecord r = findAppProcess(app, "StrictMode");
15421
15422        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
15423            Integer stackFingerprint = info.hashCode();
15424            boolean logIt = true;
15425            synchronized (mAlreadyLoggedViolatedStacks) {
15426                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
15427                    logIt = false;
15428                    // TODO: sub-sample into EventLog for these, with
15429                    // the info.durationMillis?  Then we'd get
15430                    // the relative pain numbers, without logging all
15431                    // the stack traces repeatedly.  We'd want to do
15432                    // likewise in the client code, which also does
15433                    // dup suppression, before the Binder call.
15434                } else {
15435                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
15436                        mAlreadyLoggedViolatedStacks.clear();
15437                    }
15438                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
15439                }
15440            }
15441            if (logIt) {
15442                logStrictModeViolationToDropBox(r, info);
15443            }
15444        }
15445
15446        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
15447            AppErrorResult result = new AppErrorResult();
15448            synchronized (this) {
15449                final long origId = Binder.clearCallingIdentity();
15450
15451                Message msg = Message.obtain();
15452                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
15453                HashMap<String, Object> data = new HashMap<String, Object>();
15454                data.put("result", result);
15455                data.put("app", r);
15456                data.put("violationMask", violationMask);
15457                data.put("info", info);
15458                msg.obj = data;
15459                mUiHandler.sendMessage(msg);
15460
15461                Binder.restoreCallingIdentity(origId);
15462            }
15463            int res = result.get();
15464            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
15465        }
15466    }
15467
15468    // Depending on the policy in effect, there could be a bunch of
15469    // these in quick succession so we try to batch these together to
15470    // minimize disk writes, number of dropbox entries, and maximize
15471    // compression, by having more fewer, larger records.
15472    private void logStrictModeViolationToDropBox(
15473            ProcessRecord process,
15474            StrictMode.ViolationInfo info) {
15475        if (info == null) {
15476            return;
15477        }
15478        final boolean isSystemApp = process == null ||
15479                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
15480                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
15481        final String processName = process == null ? "unknown" : process.processName;
15482        final DropBoxManager dbox = (DropBoxManager)
15483                mContext.getSystemService(Context.DROPBOX_SERVICE);
15484
15485        // Exit early if the dropbox isn't configured to accept this report type.
15486        final String dropboxTag = processClass(process) + "_strictmode";
15487        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15488
15489        final StringBuilder sb = new StringBuilder(1024);
15490        synchronized (sb) {
15491            appendDropBoxProcessHeaders(process, processName, sb);
15492            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15493            sb.append("System-App: ").append(isSystemApp).append("\n");
15494            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
15495            if (info.violationNumThisLoop != 0) {
15496                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
15497            }
15498            if (info.numAnimationsRunning != 0) {
15499                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
15500            }
15501            if (info.broadcastIntentAction != null) {
15502                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
15503            }
15504            if (info.durationMillis != -1) {
15505                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
15506            }
15507            if (info.numInstances != -1) {
15508                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
15509            }
15510            if (info.tags != null) {
15511                for (String tag : info.tags) {
15512                    sb.append("Span-Tag: ").append(tag).append("\n");
15513                }
15514            }
15515            sb.append("\n");
15516            sb.append(info.getStackTrace());
15517            sb.append("\n");
15518            if (info.getViolationDetails() != null) {
15519                sb.append(info.getViolationDetails());
15520                sb.append("\n");
15521            }
15522        }
15523
15524        final String res = sb.toString();
15525        IoThread.getHandler().post(() -> {
15526            dbox.addText(dropboxTag, res);
15527        });
15528    }
15529
15530    /**
15531     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
15532     * @param app object of the crashing app, null for the system server
15533     * @param tag reported by the caller
15534     * @param system whether this wtf is coming from the system
15535     * @param crashInfo describing the context of the error
15536     * @return true if the process should exit immediately (WTF is fatal)
15537     */
15538    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
15539            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15540        final int callingUid = Binder.getCallingUid();
15541        final int callingPid = Binder.getCallingPid();
15542
15543        if (system) {
15544            // If this is coming from the system, we could very well have low-level
15545            // system locks held, so we want to do this all asynchronously.  And we
15546            // never want this to become fatal, so there is that too.
15547            mHandler.post(new Runnable() {
15548                @Override public void run() {
15549                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
15550                }
15551            });
15552            return false;
15553        }
15554
15555        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
15556                crashInfo);
15557
15558        final boolean isFatal = Build.IS_ENG || Settings.Global
15559                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
15560        final boolean isSystem = (r == null) || r.persistent;
15561
15562        if (isFatal && !isSystem) {
15563            mAppErrors.crashApplication(r, crashInfo);
15564            return true;
15565        } else {
15566            return false;
15567        }
15568    }
15569
15570    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
15571            final ApplicationErrorReport.CrashInfo crashInfo) {
15572        final ProcessRecord r = findAppProcess(app, "WTF");
15573        final String processName = app == null ? "system_server"
15574                : (r == null ? "unknown" : r.processName);
15575
15576        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
15577                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
15578
15579        StatsLog.write(StatsLog.WTF_OCCURRED, callingUid, tag, processName,
15580                callingPid);
15581
15582        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
15583
15584        return r;
15585    }
15586
15587    /**
15588     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
15589     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
15590     */
15591    private ProcessRecord findAppProcess(IBinder app, String reason) {
15592        if (app == null) {
15593            return null;
15594        }
15595
15596        synchronized (this) {
15597            final int NP = mProcessNames.getMap().size();
15598            for (int ip=0; ip<NP; ip++) {
15599                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
15600                final int NA = apps.size();
15601                for (int ia=0; ia<NA; ia++) {
15602                    ProcessRecord p = apps.valueAt(ia);
15603                    if (p.thread != null && p.thread.asBinder() == app) {
15604                        return p;
15605                    }
15606                }
15607            }
15608
15609            Slog.w(TAG, "Can't find mystery application for " + reason
15610                    + " from pid=" + Binder.getCallingPid()
15611                    + " uid=" + Binder.getCallingUid() + ": " + app);
15612            return null;
15613        }
15614    }
15615
15616    /**
15617     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
15618     * to append various headers to the dropbox log text.
15619     */
15620    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
15621            StringBuilder sb) {
15622        // Watchdog thread ends up invoking this function (with
15623        // a null ProcessRecord) to add the stack file to dropbox.
15624        // Do not acquire a lock on this (am) in such cases, as it
15625        // could cause a potential deadlock, if and when watchdog
15626        // is invoked due to unavailability of lock on am and it
15627        // would prevent watchdog from killing system_server.
15628        if (process == null) {
15629            sb.append("Process: ").append(processName).append("\n");
15630            return;
15631        }
15632        // Note: ProcessRecord 'process' is guarded by the service
15633        // instance.  (notably process.pkgList, which could otherwise change
15634        // concurrently during execution of this method)
15635        synchronized (this) {
15636            sb.append("Process: ").append(processName).append("\n");
15637            sb.append("PID: ").append(process.pid).append("\n");
15638            int flags = process.info.flags;
15639            IPackageManager pm = AppGlobals.getPackageManager();
15640            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
15641            for (int ip=0; ip<process.pkgList.size(); ip++) {
15642                String pkg = process.pkgList.keyAt(ip);
15643                sb.append("Package: ").append(pkg);
15644                try {
15645                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
15646                    if (pi != null) {
15647                        sb.append(" v").append(pi.getLongVersionCode());
15648                        if (pi.versionName != null) {
15649                            sb.append(" (").append(pi.versionName).append(")");
15650                        }
15651                    }
15652                } catch (RemoteException e) {
15653                    Slog.e(TAG, "Error getting package info: " + pkg, e);
15654                }
15655                sb.append("\n");
15656            }
15657            if (process.info.isInstantApp()) {
15658                sb.append("Instant-App: true\n");
15659            }
15660        }
15661    }
15662
15663    private static String processClass(ProcessRecord process) {
15664        if (process == null || process.pid == MY_PID) {
15665            return "system_server";
15666        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15667            return "system_app";
15668        } else {
15669            return "data_app";
15670        }
15671    }
15672
15673    private volatile long mWtfClusterStart;
15674    private volatile int mWtfClusterCount;
15675
15676    /**
15677     * Write a description of an error (crash, WTF, ANR) to the drop box.
15678     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
15679     * @param process which caused the error, null means the system server
15680     * @param activity which triggered the error, null if unknown
15681     * @param parent activity related to the error, null if unknown
15682     * @param subject line related to the error, null if absent
15683     * @param report in long form describing the error, null if absent
15684     * @param dataFile text file to include in the report, null if none
15685     * @param crashInfo giving an application stack trace, null if absent
15686     */
15687    public void addErrorToDropBox(String eventType,
15688            ProcessRecord process, String processName, ActivityRecord activity,
15689            ActivityRecord parent, String subject,
15690            final String report, final File dataFile,
15691            final ApplicationErrorReport.CrashInfo crashInfo) {
15692        // NOTE -- this must never acquire the ActivityManagerService lock,
15693        // otherwise the watchdog may be prevented from resetting the system.
15694
15695        // Bail early if not published yet
15696        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
15697        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
15698
15699        // Exit early if the dropbox isn't configured to accept this report type.
15700        final String dropboxTag = processClass(process) + "_" + eventType;
15701        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15702
15703        // Rate-limit how often we're willing to do the heavy lifting below to
15704        // collect and record logs; currently 5 logs per 10 second period.
15705        final long now = SystemClock.elapsedRealtime();
15706        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
15707            mWtfClusterStart = now;
15708            mWtfClusterCount = 1;
15709        } else {
15710            if (mWtfClusterCount++ >= 5) return;
15711        }
15712
15713        final StringBuilder sb = new StringBuilder(1024);
15714        appendDropBoxProcessHeaders(process, processName, sb);
15715        if (process != null) {
15716            sb.append("Foreground: ")
15717                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
15718                    .append("\n");
15719        }
15720        if (activity != null) {
15721            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
15722        }
15723        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
15724            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
15725        }
15726        if (parent != null && parent != activity) {
15727            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
15728        }
15729        if (subject != null) {
15730            sb.append("Subject: ").append(subject).append("\n");
15731        }
15732        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15733        if (Debug.isDebuggerConnected()) {
15734            sb.append("Debugger: Connected\n");
15735        }
15736        sb.append("\n");
15737
15738        // Do the rest in a worker thread to avoid blocking the caller on I/O
15739        // (After this point, we shouldn't access AMS internal data structures.)
15740        Thread worker = new Thread("Error dump: " + dropboxTag) {
15741            @Override
15742            public void run() {
15743                if (report != null) {
15744                    sb.append(report);
15745                }
15746
15747                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
15748                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
15749                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
15750                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
15751
15752                if (dataFile != null && maxDataFileSize > 0) {
15753                    try {
15754                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
15755                                    "\n\n[[TRUNCATED]]"));
15756                    } catch (IOException e) {
15757                        Slog.e(TAG, "Error reading " + dataFile, e);
15758                    }
15759                }
15760                if (crashInfo != null && crashInfo.stackTrace != null) {
15761                    sb.append(crashInfo.stackTrace);
15762                }
15763
15764                if (lines > 0) {
15765                    sb.append("\n");
15766
15767                    // Merge several logcat streams, and take the last N lines
15768                    InputStreamReader input = null;
15769                    try {
15770                        java.lang.Process logcat = new ProcessBuilder(
15771                                "/system/bin/timeout", "-k", "15s", "10s",
15772                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
15773                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
15774                                        .redirectErrorStream(true).start();
15775
15776                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
15777                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
15778                        input = new InputStreamReader(logcat.getInputStream());
15779
15780                        int num;
15781                        char[] buf = new char[8192];
15782                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
15783                    } catch (IOException e) {
15784                        Slog.e(TAG, "Error running logcat", e);
15785                    } finally {
15786                        if (input != null) try { input.close(); } catch (IOException e) {}
15787                    }
15788                }
15789
15790                dbox.addText(dropboxTag, sb.toString());
15791            }
15792        };
15793
15794        if (process == null) {
15795            // If process is null, we are being called from some internal code
15796            // and may be about to die -- run this synchronously.
15797            final int oldMask = StrictMode.allowThreadDiskWritesMask();
15798            try {
15799                worker.run();
15800            } finally {
15801                StrictMode.setThreadPolicyMask(oldMask);
15802            }
15803        } else {
15804            worker.start();
15805        }
15806    }
15807
15808    @Override
15809    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
15810        enforceNotIsolatedCaller("getProcessesInErrorState");
15811        // assume our apps are happy - lazy create the list
15812        List<ActivityManager.ProcessErrorStateInfo> errList = null;
15813
15814        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15815                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
15816        int userId = UserHandle.getUserId(Binder.getCallingUid());
15817
15818        synchronized (this) {
15819
15820            // iterate across all processes
15821            for (int i=mLruProcesses.size()-1; i>=0; i--) {
15822                ProcessRecord app = mLruProcesses.get(i);
15823                if (!allUsers && app.userId != userId) {
15824                    continue;
15825                }
15826                if ((app.thread != null) && (app.crashing || app.notResponding)) {
15827                    // This one's in trouble, so we'll generate a report for it
15828                    // crashes are higher priority (in case there's a crash *and* an anr)
15829                    ActivityManager.ProcessErrorStateInfo report = null;
15830                    if (app.crashing) {
15831                        report = app.crashingReport;
15832                    } else if (app.notResponding) {
15833                        report = app.notRespondingReport;
15834                    }
15835
15836                    if (report != null) {
15837                        if (errList == null) {
15838                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
15839                        }
15840                        errList.add(report);
15841                    } else {
15842                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
15843                                " crashing = " + app.crashing +
15844                                " notResponding = " + app.notResponding);
15845                    }
15846                }
15847            }
15848        }
15849
15850        return errList;
15851    }
15852
15853    static int procStateToImportance(int procState, int memAdj,
15854            ActivityManager.RunningAppProcessInfo currApp,
15855            int clientTargetSdk) {
15856        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
15857                procState, clientTargetSdk);
15858        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
15859            currApp.lru = memAdj;
15860        } else {
15861            currApp.lru = 0;
15862        }
15863        return imp;
15864    }
15865
15866    private void fillInProcMemInfo(ProcessRecord app,
15867            ActivityManager.RunningAppProcessInfo outInfo,
15868            int clientTargetSdk) {
15869        outInfo.pid = app.pid;
15870        outInfo.uid = app.info.uid;
15871        if (mHeavyWeightProcess == app) {
15872            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
15873        }
15874        if (app.persistent) {
15875            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
15876        }
15877        if (app.activities.size() > 0) {
15878            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
15879        }
15880        outInfo.lastTrimLevel = app.trimMemoryLevel;
15881        int adj = app.curAdj;
15882        int procState = app.curProcState;
15883        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
15884        outInfo.importanceReasonCode = app.adjTypeCode;
15885        outInfo.processState = app.curProcState;
15886    }
15887
15888    @Override
15889    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
15890        enforceNotIsolatedCaller("getRunningAppProcesses");
15891
15892        final int callingUid = Binder.getCallingUid();
15893        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15894
15895        // Lazy instantiation of list
15896        List<ActivityManager.RunningAppProcessInfo> runList = null;
15897        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15898                callingUid) == PackageManager.PERMISSION_GRANTED;
15899        final int userId = UserHandle.getUserId(callingUid);
15900        final boolean allUids = isGetTasksAllowed(
15901                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
15902
15903        synchronized (this) {
15904            // Iterate across all processes
15905            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15906                ProcessRecord app = mLruProcesses.get(i);
15907                if ((!allUsers && app.userId != userId)
15908                        || (!allUids && app.uid != callingUid)) {
15909                    continue;
15910                }
15911                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
15912                    // Generate process state info for running application
15913                    ActivityManager.RunningAppProcessInfo currApp =
15914                        new ActivityManager.RunningAppProcessInfo(app.processName,
15915                                app.pid, app.getPackageList());
15916                    fillInProcMemInfo(app, currApp, clientTargetSdk);
15917                    if (app.adjSource instanceof ProcessRecord) {
15918                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
15919                        currApp.importanceReasonImportance =
15920                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
15921                                        app.adjSourceProcState);
15922                    } else if (app.adjSource instanceof ActivityRecord) {
15923                        ActivityRecord r = (ActivityRecord)app.adjSource;
15924                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
15925                    }
15926                    if (app.adjTarget instanceof ComponentName) {
15927                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
15928                    }
15929                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
15930                    //        + " lru=" + currApp.lru);
15931                    if (runList == null) {
15932                        runList = new ArrayList<>();
15933                    }
15934                    runList.add(currApp);
15935                }
15936            }
15937        }
15938        return runList;
15939    }
15940
15941    @Override
15942    public List<ApplicationInfo> getRunningExternalApplications() {
15943        enforceNotIsolatedCaller("getRunningExternalApplications");
15944        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
15945        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
15946        if (runningApps != null && runningApps.size() > 0) {
15947            Set<String> extList = new HashSet<String>();
15948            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
15949                if (app.pkgList != null) {
15950                    for (String pkg : app.pkgList) {
15951                        extList.add(pkg);
15952                    }
15953                }
15954            }
15955            IPackageManager pm = AppGlobals.getPackageManager();
15956            for (String pkg : extList) {
15957                try {
15958                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
15959                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
15960                        retList.add(info);
15961                    }
15962                } catch (RemoteException e) {
15963                }
15964            }
15965        }
15966        return retList;
15967    }
15968
15969    @Override
15970    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outState) {
15971        if (outState == null) {
15972            throw new IllegalArgumentException("outState is null");
15973        }
15974        enforceNotIsolatedCaller("getMyMemoryState");
15975
15976        final int callingUid = Binder.getCallingUid();
15977        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15978
15979        synchronized (this) {
15980            ProcessRecord proc;
15981            synchronized (mPidsSelfLocked) {
15982                proc = mPidsSelfLocked.get(Binder.getCallingPid());
15983            }
15984            if (proc != null) {
15985                fillInProcMemInfo(proc, outState, clientTargetSdk);
15986            }
15987        }
15988    }
15989
15990    @Override
15991    public int getMemoryTrimLevel() {
15992        enforceNotIsolatedCaller("getMyMemoryState");
15993        synchronized (this) {
15994            return mLastMemoryLevel;
15995        }
15996    }
15997
15998    @Override
15999    public void onShellCommand(FileDescriptor in, FileDescriptor out,
16000            FileDescriptor err, String[] args, ShellCallback callback,
16001            ResultReceiver resultReceiver) {
16002        (new ActivityManagerShellCommand(this, false)).exec(
16003                this, in, out, err, args, callback, resultReceiver);
16004    }
16005
16006    SleepToken acquireSleepToken(String tag, int displayId) {
16007        synchronized (this) {
16008            final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
16009            updateSleepIfNeededLocked();
16010            return token;
16011        }
16012    }
16013
16014    @Override
16015    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
16016        PriorityDump.dump(mPriorityDumper, fd, pw, args);
16017    }
16018
16019    /**
16020     * Wrapper function to print out debug data filtered by specified arguments.
16021    */
16022    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
16023        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
16024
16025        boolean dumpAll = false;
16026        boolean dumpClient = false;
16027        boolean dumpCheckin = false;
16028        boolean dumpCheckinFormat = false;
16029        boolean dumpNormalPriority = false;
16030        boolean dumpVisibleStacksOnly = false;
16031        boolean dumpFocusedStackOnly = false;
16032        String dumpPackage = null;
16033
16034        int opti = 0;
16035        while (opti < args.length) {
16036            String opt = args[opti];
16037            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16038                break;
16039            }
16040            opti++;
16041            if ("-a".equals(opt)) {
16042                dumpAll = true;
16043            } else if ("-c".equals(opt)) {
16044                dumpClient = true;
16045            } else if ("-v".equals(opt)) {
16046                dumpVisibleStacksOnly = true;
16047            } else if ("-f".equals(opt)) {
16048                dumpFocusedStackOnly = true;
16049            } else if ("-p".equals(opt)) {
16050                if (opti < args.length) {
16051                    dumpPackage = args[opti];
16052                    opti++;
16053                } else {
16054                    pw.println("Error: -p option requires package argument");
16055                    return;
16056                }
16057                dumpClient = true;
16058            } else if ("--checkin".equals(opt)) {
16059                dumpCheckin = dumpCheckinFormat = true;
16060            } else if ("-C".equals(opt)) {
16061                dumpCheckinFormat = true;
16062            } else if ("--normal-priority".equals(opt)) {
16063                dumpNormalPriority = true;
16064            } else if ("-h".equals(opt)) {
16065                ActivityManagerShellCommand.dumpHelp(pw, true);
16066                return;
16067            } else {
16068                pw.println("Unknown argument: " + opt + "; use -h for help");
16069            }
16070        }
16071
16072        long origId = Binder.clearCallingIdentity();
16073
16074        if (useProto) {
16075            final ProtoOutputStream proto = new ProtoOutputStream(fd);
16076            String cmd = opti < args.length ? args[opti] : "";
16077            opti++;
16078
16079            if ("activities".equals(cmd) || "a".equals(cmd)) {
16080                // output proto is ActivityManagerServiceDumpActivitiesProto
16081                synchronized (this) {
16082                    writeActivitiesToProtoLocked(proto);
16083                }
16084            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
16085                // output proto is ActivityManagerServiceDumpBroadcastsProto
16086                synchronized (this) {
16087                    writeBroadcastsToProtoLocked(proto);
16088                }
16089            } else if ("provider".equals(cmd)) {
16090                String[] newArgs;
16091                String name;
16092                if (opti >= args.length) {
16093                    name = null;
16094                    newArgs = EMPTY_STRING_ARRAY;
16095                } else {
16096                    name = args[opti];
16097                    opti++;
16098                    newArgs = new String[args.length - opti];
16099                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16100                            args.length - opti);
16101                }
16102                if (!dumpProviderProto(fd, pw, name, newArgs)) {
16103                    pw.println("No providers match: " + name);
16104                    pw.println("Use -h for help.");
16105                }
16106            } else if ("service".equals(cmd)) {
16107                // output proto is ActivityManagerServiceDumpServicesProto
16108                mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
16109            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
16110                if (opti < args.length) {
16111                    dumpPackage = args[opti];
16112                    opti++;
16113                }
16114                // output proto is ProcessProto
16115                synchronized (this) {
16116                    writeProcessesToProtoLocked(proto, dumpPackage);
16117                }
16118            } else {
16119                // default option, dump everything, output is ActivityManagerServiceProto
16120                synchronized (this) {
16121                    long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
16122                    writeActivitiesToProtoLocked(proto);
16123                    proto.end(activityToken);
16124
16125                    long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
16126                    writeBroadcastsToProtoLocked(proto);
16127                    proto.end(broadcastToken);
16128
16129                    long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
16130                    mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
16131                    proto.end(serviceToken);
16132
16133                    long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
16134                    writeProcessesToProtoLocked(proto, dumpPackage);
16135                    proto.end(processToken);
16136                }
16137            }
16138            proto.flush();
16139            Binder.restoreCallingIdentity(origId);
16140            return;
16141        }
16142
16143        int dumpAppId = getAppId(dumpPackage);
16144        boolean more = false;
16145        // Is the caller requesting to dump a particular piece of data?
16146        if (opti < args.length) {
16147            String cmd = args[opti];
16148            opti++;
16149            if ("activities".equals(cmd) || "a".equals(cmd)) {
16150                synchronized (this) {
16151                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
16152                }
16153            } else if ("lastanr".equals(cmd)) {
16154                synchronized (this) {
16155                    dumpLastANRLocked(pw);
16156                }
16157            } else if ("starter".equals(cmd)) {
16158                synchronized (this) {
16159                    dumpActivityStarterLocked(pw, dumpPackage);
16160                }
16161            } else if ("containers".equals(cmd)) {
16162                synchronized (this) {
16163                    dumpActivityContainersLocked(pw);
16164                }
16165            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
16166                synchronized (this) {
16167                    if (mRecentTasks != null) {
16168                        mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
16169                    }
16170                }
16171            } else if ("binder-proxies".equals(cmd)) {
16172                if (opti >= args.length) {
16173                    dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
16174                            "Counts of Binder Proxies held by SYSTEM");
16175                } else {
16176                    String uid = args[opti];
16177                    opti++;
16178                    // Ensure Binder Proxy Count is as up to date as possible
16179                    System.gc();
16180                    System.runFinalization();
16181                    System.gc();
16182                    pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
16183                }
16184            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
16185                if (opti < args.length) {
16186                    dumpPackage = args[opti];
16187                    opti++;
16188                }
16189                synchronized (this) {
16190                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
16191                }
16192            } else if ("broadcast-stats".equals(cmd)) {
16193                if (opti < args.length) {
16194                    dumpPackage = args[opti];
16195                    opti++;
16196                }
16197                synchronized (this) {
16198                    if (dumpCheckinFormat) {
16199                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
16200                                dumpPackage);
16201                    } else {
16202                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
16203                    }
16204                }
16205            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
16206                if (opti < args.length) {
16207                    dumpPackage = args[opti];
16208                    opti++;
16209                }
16210                synchronized (this) {
16211                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
16212                }
16213            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
16214                if (opti < args.length) {
16215                    dumpPackage = args[opti];
16216                    opti++;
16217                }
16218                synchronized (this) {
16219                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
16220                }
16221            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
16222                synchronized (this) {
16223                    dumpOomLocked(fd, pw, args, opti, true);
16224                }
16225            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
16226                synchronized (this) {
16227                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
16228                }
16229            } else if ("provider".equals(cmd)) {
16230                String[] newArgs;
16231                String name;
16232                if (opti >= args.length) {
16233                    name = null;
16234                    newArgs = EMPTY_STRING_ARRAY;
16235                } else {
16236                    name = args[opti];
16237                    opti++;
16238                    newArgs = new String[args.length - opti];
16239                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16240                }
16241                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
16242                    pw.println("No providers match: " + name);
16243                    pw.println("Use -h for help.");
16244                }
16245            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
16246                synchronized (this) {
16247                    dumpProvidersLocked(fd, pw, args, opti, true, null);
16248                }
16249            } else if ("service".equals(cmd)) {
16250                String[] newArgs;
16251                String name;
16252                if (opti >= args.length) {
16253                    name = null;
16254                    newArgs = EMPTY_STRING_ARRAY;
16255                } else {
16256                    name = args[opti];
16257                    opti++;
16258                    newArgs = new String[args.length - opti];
16259                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16260                            args.length - opti);
16261                }
16262                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
16263                    pw.println("No services match: " + name);
16264                    pw.println("Use -h for help.");
16265                }
16266            } else if ("package".equals(cmd)) {
16267                String[] newArgs;
16268                if (opti >= args.length) {
16269                    pw.println("package: no package name specified");
16270                    pw.println("Use -h for help.");
16271                } else {
16272                    dumpPackage = args[opti];
16273                    opti++;
16274                    newArgs = new String[args.length - opti];
16275                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
16276                            args.length - opti);
16277                    args = newArgs;
16278                    opti = 0;
16279                    more = true;
16280                }
16281            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
16282                synchronized (this) {
16283                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
16284                }
16285            } else if ("settings".equals(cmd)) {
16286                synchronized (this) {
16287                    mConstants.dump(pw);
16288                }
16289            } else if ("services".equals(cmd) || "s".equals(cmd)) {
16290                if (dumpClient) {
16291                    ActiveServices.ServiceDumper dumper;
16292                    synchronized (this) {
16293                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16294                                dumpPackage);
16295                    }
16296                    dumper.dumpWithClient();
16297                } else {
16298                    synchronized (this) {
16299                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16300                                dumpPackage).dumpLocked();
16301                    }
16302                }
16303            } else if ("locks".equals(cmd)) {
16304                LockGuard.dump(fd, pw, args);
16305            } else {
16306                // Dumping a single activity?
16307                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
16308                        dumpFocusedStackOnly)) {
16309                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
16310                    int res = shell.exec(this, null, fd, null, args, null,
16311                            new ResultReceiver(null));
16312                    if (res < 0) {
16313                        pw.println("Bad activity command, or no activities match: " + cmd);
16314                        pw.println("Use -h for help.");
16315                    }
16316                }
16317            }
16318            if (!more) {
16319                Binder.restoreCallingIdentity(origId);
16320                return;
16321            }
16322        }
16323
16324        // No piece of data specified, dump everything.
16325        if (dumpCheckinFormat) {
16326            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
16327        } else if (dumpClient) {
16328            ActiveServices.ServiceDumper sdumper;
16329            synchronized (this) {
16330                mConstants.dump(pw);
16331                pw.println();
16332                if (dumpAll) {
16333                    pw.println("-------------------------------------------------------------------------------");
16334                }
16335                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16336                pw.println();
16337                if (dumpAll) {
16338                    pw.println("-------------------------------------------------------------------------------");
16339                }
16340                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16341                pw.println();
16342                if (dumpAll) {
16343                    pw.println("-------------------------------------------------------------------------------");
16344                }
16345                if (dumpAll || dumpPackage != null) {
16346                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16347                    pw.println();
16348                    if (dumpAll) {
16349                        pw.println("-------------------------------------------------------------------------------");
16350                    }
16351                }
16352                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16353                pw.println();
16354                if (dumpAll) {
16355                    pw.println("-------------------------------------------------------------------------------");
16356                }
16357                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16358                pw.println();
16359                if (dumpAll) {
16360                    pw.println("-------------------------------------------------------------------------------");
16361                }
16362                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
16363                        dumpPackage);
16364            }
16365            sdumper.dumpWithClient();
16366            pw.println();
16367            synchronized (this) {
16368                if (dumpAll) {
16369                    pw.println("-------------------------------------------------------------------------------");
16370                }
16371                if (mRecentTasks != null) {
16372                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
16373                }
16374                pw.println();
16375                if (dumpAll) {
16376                    pw.println("-------------------------------------------------------------------------------");
16377                }
16378                dumpLastANRLocked(pw);
16379                pw.println();
16380                if (dumpAll) {
16381                    pw.println("-------------------------------------------------------------------------------");
16382                }
16383                dumpActivityStarterLocked(pw, dumpPackage);
16384                pw.println();
16385                if (dumpAll) {
16386                    pw.println("-------------------------------------------------------------------------------");
16387                }
16388                dumpActivityContainersLocked(pw);
16389                pw.println();
16390                if (dumpAll) {
16391                    pw.println("-------------------------------------------------------------------------------");
16392                }
16393                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16394                if (mAssociations.size() > 0) {
16395                    pw.println();
16396                    if (dumpAll) {
16397                        pw.println("-------------------------------------------------------------------------------");
16398                    }
16399                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16400                }
16401                pw.println();
16402                if (dumpAll) {
16403                    pw.println("-------------------------------------------------------------------------------");
16404                }
16405                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16406            }
16407
16408        } else {
16409            synchronized (this) {
16410                mConstants.dump(pw);
16411                pw.println();
16412                if (dumpAll) {
16413                    pw.println("-------------------------------------------------------------------------------");
16414                }
16415                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16416                pw.println();
16417                if (dumpAll) {
16418                    pw.println("-------------------------------------------------------------------------------");
16419                }
16420                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16421                pw.println();
16422                if (dumpAll) {
16423                    pw.println("-------------------------------------------------------------------------------");
16424                }
16425                if (dumpAll || dumpPackage != null) {
16426                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16427                    pw.println();
16428                    if (dumpAll) {
16429                        pw.println("-------------------------------------------------------------------------------");
16430                    }
16431                }
16432                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16433                pw.println();
16434                if (dumpAll) {
16435                    pw.println("-------------------------------------------------------------------------------");
16436                }
16437                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16438                pw.println();
16439                if (dumpAll) {
16440                    pw.println("-------------------------------------------------------------------------------");
16441                }
16442                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
16443                        .dumpLocked();
16444                pw.println();
16445                if (dumpAll) {
16446                    pw.println("-------------------------------------------------------------------------------");
16447                }
16448                if (mRecentTasks != null) {
16449                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
16450                }
16451                pw.println();
16452                if (dumpAll) {
16453                    pw.println("-------------------------------------------------------------------------------");
16454                }
16455                dumpLastANRLocked(pw);
16456                pw.println();
16457                if (dumpAll) {
16458                    pw.println("-------------------------------------------------------------------------------");
16459                }
16460                dumpActivityStarterLocked(pw, dumpPackage);
16461                pw.println();
16462                if (dumpAll) {
16463                    pw.println("-------------------------------------------------------------------------------");
16464                }
16465                dumpActivityContainersLocked(pw);
16466                // Activities section is dumped as part of the Critical priority dump. Exclude the
16467                // section if priority is Normal.
16468                if (!dumpNormalPriority){
16469                    pw.println();
16470                    if (dumpAll) {
16471                        pw.println("-------------------------------------------------------------------------------");
16472                    }
16473                    dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16474                }
16475                if (mAssociations.size() > 0) {
16476                    pw.println();
16477                    if (dumpAll) {
16478                        pw.println("-------------------------------------------------------------------------------");
16479                    }
16480                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16481                }
16482                pw.println();
16483                if (dumpAll) {
16484                    pw.println("-------------------------------------------------------------------------------");
16485                }
16486                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16487            }
16488        }
16489        Binder.restoreCallingIdentity(origId);
16490    }
16491
16492    private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
16493        // The output proto of "activity --proto activities" is ActivityManagerServiceDumpActivitiesProto
16494        mStackSupervisor.writeToProto(proto, ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
16495    }
16496
16497    private void dumpLastANRLocked(PrintWriter pw) {
16498        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
16499        if (mLastANRState == null) {
16500            pw.println("  <no ANR has occurred since boot>");
16501        } else {
16502            pw.println(mLastANRState);
16503        }
16504    }
16505
16506    private void dumpActivityContainersLocked(PrintWriter pw) {
16507        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
16508        mStackSupervisor.dumpChildrenNames(pw, " ");
16509        pw.println(" ");
16510    }
16511
16512    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
16513        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
16514        mActivityStartController.dump(pw, "", dumpPackage);
16515    }
16516
16517    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16518            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16519        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
16520                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
16521    }
16522
16523    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16524            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
16525        pw.println(header);
16526
16527        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
16528                dumpPackage);
16529        boolean needSep = printedAnything;
16530
16531        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
16532                mStackSupervisor.getResumedActivityLocked(),
16533                dumpPackage, needSep, "  ResumedActivity: ");
16534        if (printed) {
16535            printedAnything = true;
16536            needSep = false;
16537        }
16538
16539        if (dumpPackage == null) {
16540            if (needSep) {
16541                pw.println();
16542            }
16543            printedAnything = true;
16544            mStackSupervisor.dump(pw, "  ");
16545        }
16546
16547        if (!printedAnything) {
16548            pw.println("  (nothing)");
16549        }
16550    }
16551
16552    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16553            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16554        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
16555
16556        int dumpUid = 0;
16557        if (dumpPackage != null) {
16558            IPackageManager pm = AppGlobals.getPackageManager();
16559            try {
16560                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
16561            } catch (RemoteException e) {
16562            }
16563        }
16564
16565        boolean printedAnything = false;
16566
16567        final long now = SystemClock.uptimeMillis();
16568
16569        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
16570            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
16571                    = mAssociations.valueAt(i1);
16572            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
16573                SparseArray<ArrayMap<String, Association>> sourceUids
16574                        = targetComponents.valueAt(i2);
16575                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
16576                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
16577                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
16578                        Association ass = sourceProcesses.valueAt(i4);
16579                        if (dumpPackage != null) {
16580                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
16581                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
16582                                continue;
16583                            }
16584                        }
16585                        printedAnything = true;
16586                        pw.print("  ");
16587                        pw.print(ass.mTargetProcess);
16588                        pw.print("/");
16589                        UserHandle.formatUid(pw, ass.mTargetUid);
16590                        pw.print(" <- ");
16591                        pw.print(ass.mSourceProcess);
16592                        pw.print("/");
16593                        UserHandle.formatUid(pw, ass.mSourceUid);
16594                        pw.println();
16595                        pw.print("    via ");
16596                        pw.print(ass.mTargetComponent.flattenToShortString());
16597                        pw.println();
16598                        pw.print("    ");
16599                        long dur = ass.mTime;
16600                        if (ass.mNesting > 0) {
16601                            dur += now - ass.mStartTime;
16602                        }
16603                        TimeUtils.formatDuration(dur, pw);
16604                        pw.print(" (");
16605                        pw.print(ass.mCount);
16606                        pw.print(" times)");
16607                        pw.print("  ");
16608                        for (int i=0; i<ass.mStateTimes.length; i++) {
16609                            long amt = ass.mStateTimes[i];
16610                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16611                                amt += now - ass.mLastStateUptime;
16612                            }
16613                            if (amt != 0) {
16614                                pw.print(" ");
16615                                pw.print(ProcessList.makeProcStateString(
16616                                            i + ActivityManager.MIN_PROCESS_STATE));
16617                                pw.print("=");
16618                                TimeUtils.formatDuration(amt, pw);
16619                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16620                                    pw.print("*");
16621                                }
16622                            }
16623                        }
16624                        pw.println();
16625                        if (ass.mNesting > 0) {
16626                            pw.print("    Currently active: ");
16627                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
16628                            pw.println();
16629                        }
16630                    }
16631                }
16632            }
16633
16634        }
16635
16636        if (!printedAnything) {
16637            pw.println("  (nothing)");
16638        }
16639    }
16640
16641    private int getAppId(String dumpPackage) {
16642        if (dumpPackage != null) {
16643            try {
16644                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
16645                        dumpPackage, 0);
16646                return UserHandle.getAppId(info.uid);
16647            } catch (NameNotFoundException e) {
16648                e.printStackTrace();
16649            }
16650        }
16651        return -1;
16652    }
16653
16654    boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
16655                String header, boolean needSep) {
16656        boolean printed = false;
16657        for (int i=0; i<uids.size(); i++) {
16658            UidRecord uidRec = uids.valueAt(i);
16659            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
16660                continue;
16661            }
16662            if (!printed) {
16663                printed = true;
16664                if (needSep) {
16665                    pw.println();
16666                }
16667                pw.print("  ");
16668                pw.println(header);
16669                needSep = true;
16670            }
16671            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
16672            pw.print(": "); pw.println(uidRec);
16673        }
16674        return printed;
16675    }
16676
16677    boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
16678        if(counts != null) {
16679            pw.println(header);
16680            for (int i = 0; i < counts.size(); i++) {
16681                final int uid = counts.keyAt(i);
16682                final int binderCount = counts.valueAt(i);
16683                pw.print("    UID ");
16684                pw.print(uid);
16685                pw.print(", binder count = ");
16686                pw.print(binderCount);
16687                pw.print(", package(s)= ");
16688                final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
16689                if (pkgNames != null) {
16690                    for (int j = 0; j < pkgNames.length; j++) {
16691                        pw.print(pkgNames[j]);
16692                        pw.print("; ");
16693                    }
16694                } else {
16695                    pw.print("NO PACKAGE NAME FOUND");
16696                }
16697                pw.println();
16698            }
16699            pw.println();
16700            return true;
16701        }
16702        return false;
16703    }
16704
16705    @GuardedBy("this")
16706    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16707            int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
16708        boolean needSep = false;
16709        int numPers = 0;
16710
16711        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
16712
16713        if (dumpAll) {
16714            final int NP = mProcessNames.getMap().size();
16715            for (int ip=0; ip<NP; ip++) {
16716                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16717                final int NA = procs.size();
16718                for (int ia=0; ia<NA; ia++) {
16719                    ProcessRecord r = procs.valueAt(ia);
16720                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16721                        continue;
16722                    }
16723                    if (!needSep) {
16724                        pw.println("  All known processes:");
16725                        needSep = true;
16726                    }
16727                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
16728                        pw.print(" UID "); pw.print(procs.keyAt(ia));
16729                        pw.print(" "); pw.println(r);
16730                    r.dump(pw, "    ");
16731                    if (r.persistent) {
16732                        numPers++;
16733                    }
16734                }
16735            }
16736        }
16737
16738        if (mIsolatedProcesses.size() > 0) {
16739            boolean printed = false;
16740            for (int i=0; i<mIsolatedProcesses.size(); i++) {
16741                ProcessRecord r = mIsolatedProcesses.valueAt(i);
16742                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16743                    continue;
16744                }
16745                if (!printed) {
16746                    if (needSep) {
16747                        pw.println();
16748                    }
16749                    pw.println("  Isolated process list (sorted by uid):");
16750                    printed = true;
16751                    needSep = true;
16752                }
16753                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
16754                pw.println(r);
16755            }
16756        }
16757
16758        if (mActiveInstrumentation.size() > 0) {
16759            boolean printed = false;
16760            for (int i=0; i<mActiveInstrumentation.size(); i++) {
16761                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16762                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16763                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16764                    continue;
16765                }
16766                if (!printed) {
16767                    if (needSep) {
16768                        pw.println();
16769                    }
16770                    pw.println("  Active instrumentation:");
16771                    printed = true;
16772                    needSep = true;
16773                }
16774                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
16775                pw.println(ai);
16776                ai.dump(pw, "      ");
16777            }
16778        }
16779
16780        if (mActiveUids.size() > 0) {
16781            if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
16782                needSep = true;
16783            }
16784        }
16785        if (dumpAll) {
16786            if (mValidateUids.size() > 0) {
16787                if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
16788                        needSep)) {
16789                    needSep = true;
16790                }
16791            }
16792        }
16793
16794        if (mLruProcesses.size() > 0) {
16795            if (needSep) {
16796                pw.println();
16797            }
16798            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
16799                    pw.print(" total, non-act at ");
16800                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16801                    pw.print(", non-svc at ");
16802                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16803                    pw.println("):");
16804            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
16805            needSep = true;
16806        }
16807
16808        if (dumpAll || dumpPackage != null) {
16809            synchronized (mPidsSelfLocked) {
16810                boolean printed = false;
16811                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16812                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16813                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16814                        continue;
16815                    }
16816                    if (!printed) {
16817                        if (needSep) pw.println();
16818                        needSep = true;
16819                        pw.println("  PID mappings:");
16820                        printed = true;
16821                    }
16822                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
16823                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
16824                }
16825            }
16826        }
16827
16828        if (mImportantProcesses.size() > 0) {
16829            synchronized (mPidsSelfLocked) {
16830                boolean printed = false;
16831                for (int i = 0; i< mImportantProcesses.size(); i++) {
16832                    ProcessRecord r = mPidsSelfLocked.get(
16833                            mImportantProcesses.valueAt(i).pid);
16834                    if (dumpPackage != null && (r == null
16835                            || !r.pkgList.containsKey(dumpPackage))) {
16836                        continue;
16837                    }
16838                    if (!printed) {
16839                        if (needSep) pw.println();
16840                        needSep = true;
16841                        pw.println("  Foreground Processes:");
16842                        printed = true;
16843                    }
16844                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
16845                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
16846                }
16847            }
16848        }
16849
16850        if (mPersistentStartingProcesses.size() > 0) {
16851            if (needSep) pw.println();
16852            needSep = true;
16853            pw.println("  Persisent processes that are starting:");
16854            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
16855                    "Starting Norm", "Restarting PERS", dumpPackage);
16856        }
16857
16858        if (mRemovedProcesses.size() > 0) {
16859            if (needSep) pw.println();
16860            needSep = true;
16861            pw.println("  Processes that are being removed:");
16862            dumpProcessList(pw, this, mRemovedProcesses, "    ",
16863                    "Removed Norm", "Removed PERS", dumpPackage);
16864        }
16865
16866        if (mProcessesOnHold.size() > 0) {
16867            if (needSep) pw.println();
16868            needSep = true;
16869            pw.println("  Processes that are on old until the system is ready:");
16870            dumpProcessList(pw, this, mProcessesOnHold, "    ",
16871                    "OnHold Norm", "OnHold PERS", dumpPackage);
16872        }
16873
16874        needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
16875
16876        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
16877
16878        if (dumpPackage == null) {
16879            pw.println();
16880            needSep = false;
16881            mUserController.dump(pw, dumpAll);
16882        }
16883        if (mHomeProcess != null && (dumpPackage == null
16884                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16885            if (needSep) {
16886                pw.println();
16887                needSep = false;
16888            }
16889            pw.println("  mHomeProcess: " + mHomeProcess);
16890        }
16891        if (mPreviousProcess != null && (dumpPackage == null
16892                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16893            if (needSep) {
16894                pw.println();
16895                needSep = false;
16896            }
16897            pw.println("  mPreviousProcess: " + mPreviousProcess);
16898        }
16899        if (dumpAll && (mPreviousProcess == null || dumpPackage == null
16900                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16901            StringBuilder sb = new StringBuilder(128);
16902            sb.append("  mPreviousProcessVisibleTime: ");
16903            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
16904            pw.println(sb);
16905        }
16906        if (mHeavyWeightProcess != null && (dumpPackage == null
16907                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16908            if (needSep) {
16909                pw.println();
16910                needSep = false;
16911            }
16912            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16913        }
16914        if (dumpAll && mPendingStarts.size() > 0) {
16915            if (needSep) pw.println();
16916            needSep = true;
16917            pw.println("  mPendingStarts: ");
16918            for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
16919                pw.println("    " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
16920            }
16921        }
16922        if (dumpPackage == null) {
16923            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
16924            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
16925        }
16926        if (dumpAll) {
16927            if (dumpPackage == null) {
16928                pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
16929            }
16930            if (mCompatModePackages.getPackages().size() > 0) {
16931                boolean printed = false;
16932                for (Map.Entry<String, Integer> entry
16933                        : mCompatModePackages.getPackages().entrySet()) {
16934                    String pkg = entry.getKey();
16935                    int mode = entry.getValue();
16936                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
16937                        continue;
16938                    }
16939                    if (!printed) {
16940                        pw.println("  mScreenCompatPackages:");
16941                        printed = true;
16942                    }
16943                    pw.print("    "); pw.print(pkg); pw.print(": ");
16944                            pw.print(mode); pw.println();
16945                }
16946            }
16947            final int NI = mUidObservers.getRegisteredCallbackCount();
16948            boolean printed = false;
16949            for (int i=0; i<NI; i++) {
16950                final UidObserverRegistration reg = (UidObserverRegistration)
16951                        mUidObservers.getRegisteredCallbackCookie(i);
16952                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
16953                    if (!printed) {
16954                        pw.println("  mUidObservers:");
16955                        printed = true;
16956                    }
16957                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
16958                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
16959                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
16960                        pw.print(" IDLE");
16961                    }
16962                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
16963                        pw.print(" ACT" );
16964                    }
16965                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
16966                        pw.print(" GONE");
16967                    }
16968                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
16969                        pw.print(" STATE");
16970                        pw.print(" (cut="); pw.print(reg.cutpoint);
16971                        pw.print(")");
16972                    }
16973                    pw.println();
16974                    if (reg.lastProcStates != null) {
16975                        final int NJ = reg.lastProcStates.size();
16976                        for (int j=0; j<NJ; j++) {
16977                            pw.print("      Last ");
16978                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
16979                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
16980                        }
16981                    }
16982                }
16983            }
16984            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
16985            pw.println("  mDeviceIdleExceptIdleWhitelist="
16986                    + Arrays.toString(mDeviceIdleExceptIdleWhitelist));
16987            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
16988            if (mPendingTempWhitelist.size() > 0) {
16989                pw.println("  mPendingTempWhitelist:");
16990                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
16991                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
16992                    pw.print("    ");
16993                    UserHandle.formatUid(pw, ptw.targetUid);
16994                    pw.print(": ");
16995                    TimeUtils.formatDuration(ptw.duration, pw);
16996                    pw.print(" ");
16997                    pw.println(ptw.tag);
16998                }
16999            }
17000        }
17001        if (dumpPackage == null) {
17002            pw.println("  mWakefulness="
17003                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
17004            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
17005            pw.println("  mSleeping=" + mSleeping);
17006            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
17007            if (mRunningVoice != null) {
17008                pw.println("  mRunningVoice=" + mRunningVoice);
17009                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
17010            }
17011            pw.println("  mVrController=" + mVrController);
17012        }
17013        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
17014                || mOrigWaitForDebugger) {
17015            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
17016                    || dumpPackage.equals(mOrigDebugApp)) {
17017                if (needSep) {
17018                    pw.println();
17019                    needSep = false;
17020                }
17021                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
17022                        + " mDebugTransient=" + mDebugTransient
17023                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
17024            }
17025        }
17026        if (mCurAppTimeTracker != null) {
17027            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
17028        }
17029        if (mMemWatchProcesses.getMap().size() > 0) {
17030            pw.println("  Mem watch processes:");
17031            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
17032                    = mMemWatchProcesses.getMap();
17033            for (int i=0; i<procs.size(); i++) {
17034                final String proc = procs.keyAt(i);
17035                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
17036                for (int j=0; j<uids.size(); j++) {
17037                    if (needSep) {
17038                        pw.println();
17039                        needSep = false;
17040                    }
17041                    StringBuilder sb = new StringBuilder();
17042                    sb.append("    ").append(proc).append('/');
17043                    UserHandle.formatUid(sb, uids.keyAt(j));
17044                    Pair<Long, String> val = uids.valueAt(j);
17045                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
17046                    if (val.second != null) {
17047                        sb.append(", report to ").append(val.second);
17048                    }
17049                    pw.println(sb.toString());
17050                }
17051            }
17052            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
17053            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
17054            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
17055                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
17056        }
17057        if (mTrackAllocationApp != null) {
17058            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
17059                if (needSep) {
17060                    pw.println();
17061                    needSep = false;
17062                }
17063                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
17064            }
17065        }
17066        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
17067                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
17068            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
17069                if (needSep) {
17070                    pw.println();
17071                    needSep = false;
17072                }
17073                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
17074                if (mProfilerInfo != null) {
17075                    pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
17076                            mProfilerInfo.profileFd);
17077                    pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
17078                            " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
17079                            " mStreamingOutput=" + mProfilerInfo.streamingOutput);
17080                    pw.println("  mProfileType=" + mProfileType);
17081                }
17082            }
17083        }
17084        if (mNativeDebuggingApp != null) {
17085            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
17086                if (needSep) {
17087                    pw.println();
17088                    needSep = false;
17089                }
17090                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
17091            }
17092        }
17093        if (mAllowAppSwitchUids.size() > 0) {
17094            boolean printed = false;
17095            for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
17096                ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
17097                for (int j = 0; j < types.size(); j++) {
17098                    if (dumpPackage == null ||
17099                            UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
17100                        if (needSep) {
17101                            pw.println();
17102                            needSep = false;
17103                        }
17104                        if (!printed) {
17105                            pw.println("  mAllowAppSwitchUids:");
17106                            printed = true;
17107                        }
17108                        pw.print("    User ");
17109                        pw.print(mAllowAppSwitchUids.keyAt(i));
17110                        pw.print(": Type ");
17111                        pw.print(types.keyAt(j));
17112                        pw.print(" = ");
17113                        UserHandle.formatUid(pw, types.valueAt(j).intValue());
17114                        pw.println();
17115                    }
17116                }
17117            }
17118        }
17119        if (dumpPackage == null) {
17120            if (mAlwaysFinishActivities) {
17121                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
17122            }
17123            if (mController != null) {
17124                pw.println("  mController=" + mController
17125                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
17126            }
17127            if (dumpAll) {
17128                pw.println("  Total persistent processes: " + numPers);
17129                pw.println("  mProcessesReady=" + mProcessesReady
17130                        + " mSystemReady=" + mSystemReady
17131                        + " mBooted=" + mBooted
17132                        + " mFactoryTest=" + mFactoryTest);
17133                pw.println("  mBooting=" + mBooting
17134                        + " mCallFinishBooting=" + mCallFinishBooting
17135                        + " mBootAnimationComplete=" + mBootAnimationComplete);
17136                pw.print("  mLastPowerCheckUptime=");
17137                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
17138                        pw.println("");
17139                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
17140                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
17141                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
17142                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
17143                        + " (" + mLruProcesses.size() + " total)"
17144                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
17145                        + " mNumServiceProcs=" + mNumServiceProcs
17146                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
17147                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
17148                        + " mLastMemoryLevel=" + mLastMemoryLevel
17149                        + " mLastNumProcesses=" + mLastNumProcesses);
17150                long now = SystemClock.uptimeMillis();
17151                pw.print("  mLastIdleTime=");
17152                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
17153                        pw.print(" mLowRamSinceLastIdle=");
17154                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
17155                        pw.println();
17156                pw.println();
17157                pw.print("  mUidChangeDispatchCount=");
17158                pw.print(mUidChangeDispatchCount);
17159                pw.println();
17160
17161                pw.println("  Slow UID dispatches:");
17162                final int N = mUidObservers.beginBroadcast();
17163                for (int i = 0; i < N; i++) {
17164                    UidObserverRegistration r =
17165                            (UidObserverRegistration) mUidObservers.getBroadcastCookie(i);
17166                    pw.print("    ");
17167                    pw.print(mUidObservers.getBroadcastItem(i).getClass().getTypeName());
17168                    pw.print(": ");
17169                    pw.print(r.mSlowDispatchCount);
17170                    pw.print(" / Max ");
17171                    pw.print(r.mMaxDispatchTime);
17172                    pw.println("ms");
17173                }
17174                mUidObservers.finishBroadcast();
17175
17176                pw.println();
17177                pw.println("  ServiceManager statistics:");
17178                ServiceManager.sStatLogger.dump(pw, "    ");
17179                pw.println();
17180            }
17181        }
17182        pw.println("  mForceBackgroundCheck=" + mForceBackgroundCheck);
17183    }
17184
17185    @GuardedBy("this")
17186    void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
17187        int numPers = 0;
17188
17189        final int NP = mProcessNames.getMap().size();
17190        for (int ip=0; ip<NP; ip++) {
17191            SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
17192            final int NA = procs.size();
17193            for (int ia = 0; ia<NA; ia++) {
17194                ProcessRecord r = procs.valueAt(ia);
17195                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17196                    continue;
17197                }
17198                r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PROCS);
17199                if (r.persistent) {
17200                    numPers++;
17201                }
17202            }
17203        }
17204
17205        for (int i=0; i<mIsolatedProcesses.size(); i++) {
17206            ProcessRecord r = mIsolatedProcesses.valueAt(i);
17207            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17208                continue;
17209            }
17210            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS);
17211        }
17212
17213        for (int i=0; i<mActiveInstrumentation.size(); i++) {
17214            ActiveInstrumentation ai = mActiveInstrumentation.get(i);
17215            if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
17216                    && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
17217                continue;
17218            }
17219            ai.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_INSTRUMENTATIONS);
17220        }
17221
17222        int whichAppId = getAppId(dumpPackage);
17223        for (int i=0; i<mActiveUids.size(); i++) {
17224            UidRecord uidRec = mActiveUids.valueAt(i);
17225            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
17226                continue;
17227            }
17228            uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
17229        }
17230
17231        for (int i=0; i<mValidateUids.size(); i++) {
17232            UidRecord uidRec = mValidateUids.valueAt(i);
17233            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
17234                continue;
17235            }
17236            uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VALIDATE_UIDS);
17237        }
17238
17239        if (mLruProcesses.size() > 0) {
17240            long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS);
17241            int total = mLruProcesses.size();
17242            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total);
17243            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
17244            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
17245            writeProcessOomListToProto(proto, ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, this,
17246                    mLruProcesses,false, dumpPackage);
17247            proto.end(lruToken);
17248        }
17249
17250        if (dumpPackage != null) {
17251            synchronized (mPidsSelfLocked) {
17252                for (int i=0; i<mPidsSelfLocked.size(); i++) {
17253                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
17254                    if (!r.pkgList.containsKey(dumpPackage)) {
17255                        continue;
17256                    }
17257                    r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PIDS_SELF_LOCKED);
17258                }
17259            }
17260        }
17261
17262        if (mImportantProcesses.size() > 0) {
17263            synchronized (mPidsSelfLocked) {
17264                for (int i=0; i<mImportantProcesses.size(); i++) {
17265                    ImportanceToken it = mImportantProcesses.valueAt(i);
17266                    ProcessRecord r = mPidsSelfLocked.get(it.pid);
17267                    if (dumpPackage != null && (r == null
17268                            || !r.pkgList.containsKey(dumpPackage))) {
17269                        continue;
17270                    }
17271                    it.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.IMPORTANT_PROCS);
17272                }
17273            }
17274        }
17275
17276        for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
17277            ProcessRecord r = mPersistentStartingProcesses.get(i);
17278            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17279                continue;
17280            }
17281            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PERSISTENT_STARTING_PROCS);
17282        }
17283
17284        for (int i=0; i<mRemovedProcesses.size(); i++) {
17285            ProcessRecord r = mRemovedProcesses.get(i);
17286            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17287                continue;
17288            }
17289            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.REMOVED_PROCS);
17290        }
17291
17292        for (int i=0; i<mProcessesOnHold.size(); i++) {
17293            ProcessRecord r = mProcessesOnHold.get(i);
17294            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17295                continue;
17296            }
17297            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ON_HOLD_PROCS);
17298        }
17299
17300        writeProcessesToGcToProto(proto, ActivityManagerServiceDumpProcessesProto.GC_PROCS, dumpPackage);
17301        mAppErrors.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.APP_ERRORS, dumpPackage);
17302
17303        if (dumpPackage == null) {
17304            mUserController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER);
17305            getGlobalConfiguration().writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION);
17306            proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
17307        }
17308
17309        if (mHomeProcess != null && (dumpPackage == null
17310                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
17311            mHomeProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HOME_PROC);
17312        }
17313
17314        if (mPreviousProcess != null && (dumpPackage == null
17315                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
17316            mPreviousProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC);
17317            proto.write(ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
17318        }
17319
17320        if (mHeavyWeightProcess != null && (dumpPackage == null
17321                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
17322            mHeavyWeightProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC);
17323        }
17324
17325        for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
17326            String pkg = entry.getKey();
17327            int mode = entry.getValue();
17328            if (dumpPackage == null || dumpPackage.equals(pkg)) {
17329                long compatToken = proto.start(ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES);
17330                proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
17331                proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE, mode);
17332                proto.end(compatToken);
17333            }
17334        }
17335
17336        final int NI = mUidObservers.getRegisteredCallbackCount();
17337        for (int i=0; i<NI; i++) {
17338            final UidObserverRegistration reg = (UidObserverRegistration)
17339                    mUidObservers.getRegisteredCallbackCookie(i);
17340            if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
17341                reg.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
17342            }
17343        }
17344
17345        for (int v : mDeviceIdleWhitelist) {
17346            proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_WHITELIST, v);
17347        }
17348
17349        for (int v : mDeviceIdleTempWhitelist) {
17350            proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
17351        }
17352
17353        if (mPendingTempWhitelist.size() > 0) {
17354            for (int i=0; i < mPendingTempWhitelist.size(); i++) {
17355                mPendingTempWhitelist.valueAt(i).writeToProto(proto,
17356                        ActivityManagerServiceDumpProcessesProto.PENDING_TEMP_WHITELIST);
17357            }
17358        }
17359
17360        if (dumpPackage == null) {
17361            final long sleepToken = proto.start(ActivityManagerServiceDumpProcessesProto.SLEEP_STATUS);
17362            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.WAKEFULNESS,
17363                    PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
17364            for (SleepToken st : mStackSupervisor.mSleepTokens) {
17365                proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
17366            }
17367            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
17368            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
17369            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
17370            proto.end(sleepToken);
17371
17372            if (mRunningVoice != null) {
17373                final long vrToken = proto.start(ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
17374                proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION, mRunningVoice.toString());
17375                mVoiceWakeLock.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
17376                proto.end(vrToken);
17377            }
17378
17379            mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
17380        }
17381
17382        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
17383                || mOrigWaitForDebugger) {
17384            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
17385                    || dumpPackage.equals(mOrigDebugApp)) {
17386                final long debugAppToken = proto.start(ActivityManagerServiceDumpProcessesProto.DEBUG);
17387                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
17388                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
17389                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
17390                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
17391                proto.end(debugAppToken);
17392            }
17393        }
17394
17395        if (mCurAppTimeTracker != null) {
17396            mCurAppTimeTracker.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER, true);
17397        }
17398
17399        if (mMemWatchProcesses.getMap().size() > 0) {
17400            final long token = proto.start(ActivityManagerServiceDumpProcessesProto.MEM_WATCH_PROCESSES);
17401            ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
17402            for (int i=0; i<procs.size(); i++) {
17403                final String proc = procs.keyAt(i);
17404                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
17405                final long ptoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.PROCS);
17406                proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.NAME, proc);
17407                for (int j=0; j<uids.size(); j++) {
17408                    final long utoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MEM_STATS);
17409                    Pair<Long, String> val = uids.valueAt(j);
17410                    proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
17411                    proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
17412                            DebugUtils.sizeValueToString(val.first, new StringBuilder()));
17413                    proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
17414                    proto.end(utoken);
17415                }
17416                proto.end(ptoken);
17417            }
17418
17419            final long dtoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.DUMP);
17420            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
17421            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
17422            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
17423            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
17424            proto.end(dtoken);
17425
17426            proto.end(token);
17427        }
17428
17429        if (mTrackAllocationApp != null) {
17430            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
17431                proto.write(ActivityManagerServiceDumpProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
17432            }
17433        }
17434
17435        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
17436                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
17437            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
17438                final long token = proto.start(ActivityManagerServiceDumpProcessesProto.PROFILE);
17439                proto.write(ActivityManagerServiceDumpProcessesProto.Profile.APP_NAME, mProfileApp);
17440                mProfileProc.writeToProto(proto,ActivityManagerServiceDumpProcessesProto.Profile.PROC);
17441                if (mProfilerInfo != null) {
17442                    mProfilerInfo.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Profile.INFO);
17443                    proto.write(ActivityManagerServiceDumpProcessesProto.Profile.TYPE, mProfileType);
17444                }
17445                proto.end(token);
17446            }
17447        }
17448
17449        if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
17450            proto.write(ActivityManagerServiceDumpProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
17451        }
17452
17453        if (dumpPackage == null) {
17454            proto.write(ActivityManagerServiceDumpProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
17455            if (mController != null) {
17456                final long token = proto.start(ActivityManagerServiceDumpProcessesProto.CONTROLLER);
17457                proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mController.toString());
17458                proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
17459                proto.end(token);
17460            }
17461            proto.write(ActivityManagerServiceDumpProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
17462            proto.write(ActivityManagerServiceDumpProcessesProto.PROCESSES_READY, mProcessesReady);
17463            proto.write(ActivityManagerServiceDumpProcessesProto.SYSTEM_READY, mSystemReady);
17464            proto.write(ActivityManagerServiceDumpProcessesProto.BOOTED, mBooted);
17465            proto.write(ActivityManagerServiceDumpProcessesProto.FACTORY_TEST, mFactoryTest);
17466            proto.write(ActivityManagerServiceDumpProcessesProto.BOOTING, mBooting);
17467            proto.write(ActivityManagerServiceDumpProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
17468            proto.write(ActivityManagerServiceDumpProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
17469            proto.write(ActivityManagerServiceDumpProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
17470            mStackSupervisor.mGoingToSleep.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP);
17471            mStackSupervisor.mLaunchingActivity.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY);
17472            proto.write(ActivityManagerServiceDumpProcessesProto.ADJ_SEQ, mAdjSeq);
17473            proto.write(ActivityManagerServiceDumpProcessesProto.LRU_SEQ, mLruSeq);
17474            proto.write(ActivityManagerServiceDumpProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
17475            proto.write(ActivityManagerServiceDumpProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
17476            proto.write(ActivityManagerServiceDumpProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
17477            proto.write(ActivityManagerServiceDumpProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
17478            proto.write(ActivityManagerServiceDumpProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
17479            proto.write(ActivityManagerServiceDumpProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
17480            long now = SystemClock.uptimeMillis();
17481            ProtoUtils.toDuration(proto, ActivityManagerServiceDumpProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
17482            proto.write(ActivityManagerServiceDumpProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
17483        }
17484
17485    }
17486
17487    void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
17488        if (mProcessesToGc.size() > 0) {
17489            long now = SystemClock.uptimeMillis();
17490            for (int i=0; i<mProcessesToGc.size(); i++) {
17491                ProcessRecord r = mProcessesToGc.get(i);
17492                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17493                    continue;
17494                }
17495                final long token = proto.start(fieldId);
17496                r.writeToProto(proto, ProcessToGcProto.PROC);
17497                proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
17498                proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
17499                proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
17500                proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory);
17501                proto.end(token);
17502            }
17503        }
17504    }
17505
17506    boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) {
17507        if (mProcessesToGc.size() > 0) {
17508            boolean printed = false;
17509            long now = SystemClock.uptimeMillis();
17510            for (int i=0; i<mProcessesToGc.size(); i++) {
17511                ProcessRecord proc = mProcessesToGc.get(i);
17512                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
17513                    continue;
17514                }
17515                if (!printed) {
17516                    if (needSep) pw.println();
17517                    needSep = true;
17518                    pw.println("  Processes that are waiting to GC:");
17519                    printed = true;
17520                }
17521                pw.print("    Process "); pw.println(proc);
17522                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
17523                        pw.print(", last gced=");
17524                        pw.print(now-proc.lastRequestedGc);
17525                        pw.print(" ms ago, last lowMem=");
17526                        pw.print(now-proc.lastLowMemory);
17527                        pw.println(" ms ago");
17528
17529            }
17530        }
17531        return needSep;
17532    }
17533
17534    void printOomLevel(PrintWriter pw, String name, int adj) {
17535        pw.print("    ");
17536        if (adj >= 0) {
17537            pw.print(' ');
17538            if (adj < 10) pw.print(' ');
17539        } else {
17540            if (adj > -10) pw.print(' ');
17541        }
17542        pw.print(adj);
17543        pw.print(": ");
17544        pw.print(name);
17545        pw.print(" (");
17546        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
17547        pw.println(")");
17548    }
17549
17550    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17551            int opti, boolean dumpAll) {
17552        boolean needSep = false;
17553
17554        if (mLruProcesses.size() > 0) {
17555            if (needSep) pw.println();
17556            needSep = true;
17557            pw.println("  OOM levels:");
17558            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
17559            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
17560            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
17561            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
17562            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
17563            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
17564            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
17565            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
17566            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
17567            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
17568            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
17569            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
17570            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
17571            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
17572
17573            if (needSep) pw.println();
17574            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
17575                    pw.print(" total, non-act at ");
17576                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
17577                    pw.print(", non-svc at ");
17578                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
17579                    pw.println("):");
17580            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
17581            needSep = true;
17582        }
17583
17584        dumpProcessesToGc(pw, needSep, null);
17585
17586        pw.println();
17587        pw.println("  mHomeProcess: " + mHomeProcess);
17588        pw.println("  mPreviousProcess: " + mPreviousProcess);
17589        if (mHeavyWeightProcess != null) {
17590            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
17591        }
17592
17593        return true;
17594    }
17595
17596    /**
17597     * There are three ways to call this:
17598     *  - no provider specified: dump all the providers
17599     *  - a flattened component name that matched an existing provider was specified as the
17600     *    first arg: dump that one provider
17601     *  - the first arg isn't the flattened component name of an existing provider:
17602     *    dump all providers whose component contains the first arg as a substring
17603     */
17604    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17605            int opti, boolean dumpAll) {
17606        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
17607    }
17608
17609    /**
17610     * Similar to the dumpProvider, but only dumps the first matching provider.
17611     * The provider is responsible for dumping as proto.
17612     */
17613    protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
17614            String[] args) {
17615        return mProviderMap.dumpProviderProto(fd, pw, name, args);
17616    }
17617
17618    static class ItemMatcher {
17619        ArrayList<ComponentName> components;
17620        ArrayList<String> strings;
17621        ArrayList<Integer> objects;
17622        boolean all;
17623
17624        ItemMatcher() {
17625            all = true;
17626        }
17627
17628        void build(String name) {
17629            ComponentName componentName = ComponentName.unflattenFromString(name);
17630            if (componentName != null) {
17631                if (components == null) {
17632                    components = new ArrayList<ComponentName>();
17633                }
17634                components.add(componentName);
17635                all = false;
17636            } else {
17637                int objectId = 0;
17638                // Not a '/' separated full component name; maybe an object ID?
17639                try {
17640                    objectId = Integer.parseInt(name, 16);
17641                    if (objects == null) {
17642                        objects = new ArrayList<Integer>();
17643                    }
17644                    objects.add(objectId);
17645                    all = false;
17646                } catch (RuntimeException e) {
17647                    // Not an integer; just do string match.
17648                    if (strings == null) {
17649                        strings = new ArrayList<String>();
17650                    }
17651                    strings.add(name);
17652                    all = false;
17653                }
17654            }
17655        }
17656
17657        int build(String[] args, int opti) {
17658            for (; opti<args.length; opti++) {
17659                String name = args[opti];
17660                if ("--".equals(name)) {
17661                    return opti+1;
17662                }
17663                build(name);
17664            }
17665            return opti;
17666        }
17667
17668        boolean match(Object object, ComponentName comp) {
17669            if (all) {
17670                return true;
17671            }
17672            if (components != null) {
17673                for (int i=0; i<components.size(); i++) {
17674                    if (components.get(i).equals(comp)) {
17675                        return true;
17676                    }
17677                }
17678            }
17679            if (objects != null) {
17680                for (int i=0; i<objects.size(); i++) {
17681                    if (System.identityHashCode(object) == objects.get(i)) {
17682                        return true;
17683                    }
17684                }
17685            }
17686            if (strings != null) {
17687                String flat = comp.flattenToString();
17688                for (int i=0; i<strings.size(); i++) {
17689                    if (flat.contains(strings.get(i))) {
17690                        return true;
17691                    }
17692                }
17693            }
17694            return false;
17695        }
17696    }
17697
17698    /**
17699     * There are three things that cmd can be:
17700     *  - a flattened component name that matches an existing activity
17701     *  - the cmd arg isn't the flattened component name of an existing activity:
17702     *    dump all activity whose component contains the cmd as a substring
17703     *  - A hex number of the ActivityRecord object instance.
17704     *
17705     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
17706     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
17707     */
17708    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17709            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
17710        ArrayList<ActivityRecord> activities;
17711
17712        synchronized (this) {
17713            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
17714                    dumpFocusedStackOnly);
17715        }
17716
17717        if (activities.size() <= 0) {
17718            return false;
17719        }
17720
17721        String[] newArgs = new String[args.length - opti];
17722        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
17723
17724        TaskRecord lastTask = null;
17725        boolean needSep = false;
17726        for (int i=activities.size()-1; i>=0; i--) {
17727            ActivityRecord r = activities.get(i);
17728            if (needSep) {
17729                pw.println();
17730            }
17731            needSep = true;
17732            synchronized (this) {
17733                final TaskRecord task = r.getTask();
17734                if (lastTask != task) {
17735                    lastTask = task;
17736                    pw.print("TASK "); pw.print(lastTask.affinity);
17737                            pw.print(" id="); pw.print(lastTask.taskId);
17738                            pw.print(" userId="); pw.println(lastTask.userId);
17739                    if (dumpAll) {
17740                        lastTask.dump(pw, "  ");
17741                    }
17742                }
17743            }
17744            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
17745        }
17746        return true;
17747    }
17748
17749    /**
17750     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
17751     * there is a thread associated with the activity.
17752     */
17753    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
17754            final ActivityRecord r, String[] args, boolean dumpAll) {
17755        String innerPrefix = prefix + "  ";
17756        synchronized (this) {
17757            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
17758                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
17759                    pw.print(" pid=");
17760                    if (r.app != null) pw.println(r.app.pid);
17761                    else pw.println("(not running)");
17762            if (dumpAll) {
17763                r.dump(pw, innerPrefix);
17764            }
17765        }
17766        if (r.app != null && r.app.thread != null) {
17767            // flush anything that is already in the PrintWriter since the thread is going
17768            // to write to the file descriptor directly
17769            pw.flush();
17770            try {
17771                TransferPipe tp = new TransferPipe();
17772                try {
17773                    r.app.thread.dumpActivity(tp.getWriteFd(),
17774                            r.appToken, innerPrefix, args);
17775                    tp.go(fd);
17776                } finally {
17777                    tp.kill();
17778                }
17779            } catch (IOException e) {
17780                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
17781            } catch (RemoteException e) {
17782                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
17783            }
17784        }
17785    }
17786
17787    void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
17788        if (mRegisteredReceivers.size() > 0) {
17789            Iterator it = mRegisteredReceivers.values().iterator();
17790            while (it.hasNext()) {
17791                ReceiverList r = (ReceiverList)it.next();
17792                r.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_LIST);
17793            }
17794        }
17795        mReceiverResolver.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_RESOLVER);
17796        for (BroadcastQueue q : mBroadcastQueues) {
17797            q.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
17798        }
17799        for (int user=0; user<mStickyBroadcasts.size(); user++) {
17800            long token = proto.start(ActivityManagerServiceDumpBroadcastsProto.STICKY_BROADCASTS);
17801            proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
17802            for (Map.Entry<String, ArrayList<Intent>> ent
17803                    : mStickyBroadcasts.valueAt(user).entrySet()) {
17804                long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
17805                proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
17806                for (Intent intent : ent.getValue()) {
17807                    intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
17808                            false, true, true, false);
17809                }
17810                proto.end(actionToken);
17811            }
17812            proto.end(token);
17813        }
17814
17815        long handlerToken = proto.start(ActivityManagerServiceDumpBroadcastsProto.HANDLER);
17816        proto.write(ActivityManagerServiceDumpBroadcastsProto.MainHandler.HANDLER, mHandler.toString());
17817        mHandler.getLooper().writeToProto(proto,
17818            ActivityManagerServiceDumpBroadcastsProto.MainHandler.LOOPER);
17819        proto.end(handlerToken);
17820    }
17821
17822    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17823            int opti, boolean dumpAll, String dumpPackage) {
17824        boolean needSep = false;
17825        boolean onlyHistory = false;
17826        boolean printedAnything = false;
17827
17828        if ("history".equals(dumpPackage)) {
17829            if (opti < args.length && "-s".equals(args[opti])) {
17830                dumpAll = false;
17831            }
17832            onlyHistory = true;
17833            dumpPackage = null;
17834        }
17835
17836        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
17837        if (!onlyHistory && dumpAll) {
17838            if (mRegisteredReceivers.size() > 0) {
17839                boolean printed = false;
17840                Iterator it = mRegisteredReceivers.values().iterator();
17841                while (it.hasNext()) {
17842                    ReceiverList r = (ReceiverList)it.next();
17843                    if (dumpPackage != null && (r.app == null ||
17844                            !dumpPackage.equals(r.app.info.packageName))) {
17845                        continue;
17846                    }
17847                    if (!printed) {
17848                        pw.println("  Registered Receivers:");
17849                        needSep = true;
17850                        printed = true;
17851                        printedAnything = true;
17852                    }
17853                    pw.print("  * "); pw.println(r);
17854                    r.dump(pw, "    ");
17855                }
17856            }
17857
17858            if (mReceiverResolver.dump(pw, needSep ?
17859                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
17860                    "    ", dumpPackage, false, false)) {
17861                needSep = true;
17862                printedAnything = true;
17863            }
17864        }
17865
17866        for (BroadcastQueue q : mBroadcastQueues) {
17867            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
17868            printedAnything |= needSep;
17869        }
17870
17871        needSep = true;
17872
17873        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
17874            for (int user=0; user<mStickyBroadcasts.size(); user++) {
17875                if (needSep) {
17876                    pw.println();
17877                }
17878                needSep = true;
17879                printedAnything = true;
17880                pw.print("  Sticky broadcasts for user ");
17881                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
17882                StringBuilder sb = new StringBuilder(128);
17883                for (Map.Entry<String, ArrayList<Intent>> ent
17884                        : mStickyBroadcasts.valueAt(user).entrySet()) {
17885                    pw.print("  * Sticky action "); pw.print(ent.getKey());
17886                    if (dumpAll) {
17887                        pw.println(":");
17888                        ArrayList<Intent> intents = ent.getValue();
17889                        final int N = intents.size();
17890                        for (int i=0; i<N; i++) {
17891                            sb.setLength(0);
17892                            sb.append("    Intent: ");
17893                            intents.get(i).toShortString(sb, false, true, false, false);
17894                            pw.println(sb.toString());
17895                            Bundle bundle = intents.get(i).getExtras();
17896                            if (bundle != null) {
17897                                pw.print("      ");
17898                                pw.println(bundle.toString());
17899                            }
17900                        }
17901                    } else {
17902                        pw.println("");
17903                    }
17904                }
17905            }
17906        }
17907
17908        if (!onlyHistory && dumpAll) {
17909            pw.println();
17910            for (BroadcastQueue queue : mBroadcastQueues) {
17911                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
17912                        + queue.mBroadcastsScheduled);
17913            }
17914            pw.println("  mHandler:");
17915            mHandler.dump(new PrintWriterPrinter(pw), "    ");
17916            needSep = true;
17917            printedAnything = true;
17918        }
17919
17920        if (!printedAnything) {
17921            pw.println("  (nothing)");
17922        }
17923    }
17924
17925    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17926            int opti, boolean dumpAll, String dumpPackage) {
17927        if (mCurBroadcastStats == null) {
17928            return;
17929        }
17930
17931        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
17932        final long now = SystemClock.elapsedRealtime();
17933        if (mLastBroadcastStats != null) {
17934            pw.print("  Last stats (from ");
17935            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
17936            pw.print(" to ");
17937            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
17938            pw.print(", ");
17939            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
17940                    - mLastBroadcastStats.mStartUptime, pw);
17941            pw.println(" uptime):");
17942            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17943                pw.println("    (nothing)");
17944            }
17945            pw.println();
17946        }
17947        pw.print("  Current stats (from ");
17948        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
17949        pw.print(" to now, ");
17950        TimeUtils.formatDuration(SystemClock.uptimeMillis()
17951                - mCurBroadcastStats.mStartUptime, pw);
17952        pw.println(" uptime):");
17953        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17954            pw.println("    (nothing)");
17955        }
17956    }
17957
17958    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17959            int opti, boolean fullCheckin, String dumpPackage) {
17960        if (mCurBroadcastStats == null) {
17961            return;
17962        }
17963
17964        if (mLastBroadcastStats != null) {
17965            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17966            if (fullCheckin) {
17967                mLastBroadcastStats = null;
17968                return;
17969            }
17970        }
17971        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17972        if (fullCheckin) {
17973            mCurBroadcastStats = null;
17974        }
17975    }
17976
17977    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17978            int opti, boolean dumpAll, String dumpPackage) {
17979        boolean needSep;
17980        boolean printedAnything = false;
17981
17982        ItemMatcher matcher = new ItemMatcher();
17983        matcher.build(args, opti);
17984
17985        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
17986
17987        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
17988        printedAnything |= needSep;
17989
17990        if (mLaunchingProviders.size() > 0) {
17991            boolean printed = false;
17992            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
17993                ContentProviderRecord r = mLaunchingProviders.get(i);
17994                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
17995                    continue;
17996                }
17997                if (!printed) {
17998                    if (needSep) pw.println();
17999                    needSep = true;
18000                    pw.println("  Launching content providers:");
18001                    printed = true;
18002                    printedAnything = true;
18003                }
18004                pw.print("  Launching #"); pw.print(i); pw.print(": ");
18005                        pw.println(r);
18006            }
18007        }
18008
18009        if (!printedAnything) {
18010            pw.println("  (nothing)");
18011        }
18012    }
18013
18014    @GuardedBy("this")
18015    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18016            int opti, boolean dumpAll, String dumpPackage) {
18017        boolean needSep = false;
18018        boolean printedAnything = false;
18019
18020        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
18021
18022        if (mGrantedUriPermissions.size() > 0) {
18023            boolean printed = false;
18024            int dumpUid = -2;
18025            if (dumpPackage != null) {
18026                try {
18027                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
18028                            MATCH_ANY_USER, 0);
18029                } catch (NameNotFoundException e) {
18030                    dumpUid = -1;
18031                }
18032            }
18033            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
18034                int uid = mGrantedUriPermissions.keyAt(i);
18035                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
18036                    continue;
18037                }
18038                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
18039                if (!printed) {
18040                    if (needSep) pw.println();
18041                    needSep = true;
18042                    pw.println("  Granted Uri Permissions:");
18043                    printed = true;
18044                    printedAnything = true;
18045                }
18046                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
18047                for (UriPermission perm : perms.values()) {
18048                    pw.print("    "); pw.println(perm);
18049                    if (dumpAll) {
18050                        perm.dump(pw, "      ");
18051                    }
18052                }
18053            }
18054        }
18055
18056        if (!printedAnything) {
18057            pw.println("  (nothing)");
18058        }
18059    }
18060
18061    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18062            int opti, boolean dumpAll, String dumpPackage) {
18063        boolean printed = false;
18064
18065        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
18066
18067        if (mIntentSenderRecords.size() > 0) {
18068            // Organize these by package name, so they are easier to read.
18069            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
18070            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
18071            final Iterator<WeakReference<PendingIntentRecord>> it
18072                    = mIntentSenderRecords.values().iterator();
18073            while (it.hasNext()) {
18074                WeakReference<PendingIntentRecord> ref = it.next();
18075                PendingIntentRecord rec = ref != null ? ref.get() : null;
18076                if (rec == null) {
18077                    weakRefs.add(ref);
18078                    continue;
18079                }
18080                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
18081                    continue;
18082                }
18083                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
18084                if (list == null) {
18085                    list = new ArrayList<>();
18086                    byPackage.put(rec.key.packageName, list);
18087                }
18088                list.add(rec);
18089            }
18090            for (int i = 0; i < byPackage.size(); i++) {
18091                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
18092                printed = true;
18093                pw.print("  * "); pw.print(byPackage.keyAt(i));
18094                pw.print(": "); pw.print(intents.size()); pw.println(" items");
18095                for (int j = 0; j < intents.size(); j++) {
18096                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
18097                    if (dumpAll) {
18098                        intents.get(j).dump(pw, "      ");
18099                    }
18100                }
18101            }
18102            if (weakRefs.size() > 0) {
18103                printed = true;
18104                pw.println("  * WEAK REFS:");
18105                for (int i = 0; i < weakRefs.size(); i++) {
18106                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
18107                }
18108            }
18109        }
18110
18111        if (!printed) {
18112            pw.println("  (nothing)");
18113        }
18114    }
18115
18116    private static final int dumpProcessList(PrintWriter pw,
18117            ActivityManagerService service, List list,
18118            String prefix, String normalLabel, String persistentLabel,
18119            String dumpPackage) {
18120        int numPers = 0;
18121        final int N = list.size()-1;
18122        for (int i=N; i>=0; i--) {
18123            ProcessRecord r = (ProcessRecord)list.get(i);
18124            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
18125                continue;
18126            }
18127            pw.println(String.format("%s%s #%2d: %s",
18128                    prefix, (r.persistent ? persistentLabel : normalLabel),
18129                    i, r.toString()));
18130            if (r.persistent) {
18131                numPers++;
18132            }
18133        }
18134        return numPers;
18135    }
18136
18137    private static final ArrayList<Pair<ProcessRecord, Integer>>
18138        sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) {
18139        ArrayList<Pair<ProcessRecord, Integer>> list
18140                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
18141        for (int i=0; i<origList.size(); i++) {
18142            ProcessRecord r = origList.get(i);
18143            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
18144                continue;
18145            }
18146            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
18147        }
18148
18149        Comparator<Pair<ProcessRecord, Integer>> comparator
18150                = new Comparator<Pair<ProcessRecord, Integer>>() {
18151            @Override
18152            public int compare(Pair<ProcessRecord, Integer> object1,
18153                    Pair<ProcessRecord, Integer> object2) {
18154                if (object1.first.setAdj != object2.first.setAdj) {
18155                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
18156                }
18157                if (object1.first.setProcState != object2.first.setProcState) {
18158                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
18159                }
18160                if (object1.second.intValue() != object2.second.intValue()) {
18161                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
18162                }
18163                return 0;
18164            }
18165        };
18166
18167        Collections.sort(list, comparator);
18168        return list;
18169    }
18170
18171    private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
18172            ActivityManagerService service, List<ProcessRecord> origList,
18173            boolean inclDetails, String dumpPackage) {
18174        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
18175        if (list.isEmpty()) return false;
18176
18177        final long curUptime = SystemClock.uptimeMillis();
18178
18179        for (int i = list.size() - 1; i >= 0; i--) {
18180            ProcessRecord r = list.get(i).first;
18181            long token = proto.start(fieldId);
18182            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
18183            proto.write(ProcessOomProto.PERSISTENT, r.persistent);
18184            proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
18185            proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
18186            int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
18187            switch (r.setSchedGroup) {
18188                case ProcessList.SCHED_GROUP_BACKGROUND:
18189                    schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
18190                    break;
18191                case ProcessList.SCHED_GROUP_DEFAULT:
18192                    schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
18193                    break;
18194                case ProcessList.SCHED_GROUP_TOP_APP:
18195                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
18196                    break;
18197                case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
18198                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
18199                    break;
18200            }
18201            if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
18202                proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
18203            }
18204            if (r.foregroundActivities) {
18205                proto.write(ProcessOomProto.ACTIVITIES, true);
18206            } else if (r.foregroundServices) {
18207                proto.write(ProcessOomProto.SERVICES, true);
18208            }
18209            proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
18210            proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
18211            r.writeToProto(proto, ProcessOomProto.PROC);
18212            proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
18213            if (r.adjSource != null || r.adjTarget != null) {
18214                if (r.adjTarget instanceof  ComponentName) {
18215                    ComponentName cn = (ComponentName) r.adjTarget;
18216                    cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
18217                } else if (r.adjTarget != null) {
18218                    proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
18219                }
18220                if (r.adjSource instanceof ProcessRecord) {
18221                    ProcessRecord p = (ProcessRecord) r.adjSource;
18222                    p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
18223                } else if (r.adjSource != null) {
18224                    proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
18225                }
18226            }
18227            if (inclDetails) {
18228                long detailToken = proto.start(ProcessOomProto.DETAIL);
18229                proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
18230                proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
18231                proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
18232                proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
18233                proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
18234                proto.write(ProcessOomProto.Detail.CURRENT_STATE,
18235                        ProcessList.makeProcStateProtoEnum(r.curProcState));
18236                proto.write(ProcessOomProto.Detail.SET_STATE,
18237                        ProcessList.makeProcStateProtoEnum(r.setProcState));
18238                proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
18239                        r.lastPss*1024, new StringBuilder()));
18240                proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
18241                        r.lastSwapPss*1024, new StringBuilder()));
18242                proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
18243                        r.lastCachedPss*1024, new StringBuilder()));
18244                proto.write(ProcessOomProto.Detail.CACHED, r.cached);
18245                proto.write(ProcessOomProto.Detail.EMPTY, r.empty);
18246                proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient);
18247
18248                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
18249                    if (r.lastCpuTime != 0) {
18250                        long uptimeSince = curUptime - service.mLastPowerCheckUptime;
18251                        long timeUsed = r.curCpuTime - r.lastCpuTime;
18252                        long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
18253                        proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
18254                        proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
18255                        proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
18256                                (100.0*timeUsed)/uptimeSince);
18257                        proto.end(cpuTimeToken);
18258                    }
18259                }
18260                proto.end(detailToken);
18261            }
18262            proto.end(token);
18263        }
18264
18265        return true;
18266    }
18267
18268    private static final boolean dumpProcessOomList(PrintWriter pw,
18269            ActivityManagerService service, List<ProcessRecord> origList,
18270            String prefix, String normalLabel, String persistentLabel,
18271            boolean inclDetails, String dumpPackage) {
18272
18273        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
18274        if (list.isEmpty()) return false;
18275
18276        final long curUptime = SystemClock.uptimeMillis();
18277        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
18278
18279        for (int i=list.size()-1; i>=0; i--) {
18280            ProcessRecord r = list.get(i).first;
18281            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
18282            char schedGroup;
18283            switch (r.setSchedGroup) {
18284                case ProcessList.SCHED_GROUP_BACKGROUND:
18285                    schedGroup = 'B';
18286                    break;
18287                case ProcessList.SCHED_GROUP_DEFAULT:
18288                    schedGroup = 'F';
18289                    break;
18290                case ProcessList.SCHED_GROUP_TOP_APP:
18291                    schedGroup = 'T';
18292                    break;
18293                case ProcessList.SCHED_GROUP_RESTRICTED:
18294                    schedGroup = 'R';
18295                    break;
18296                default:
18297                    schedGroup = '?';
18298                    break;
18299            }
18300            char foreground;
18301            if (r.foregroundActivities) {
18302                foreground = 'A';
18303            } else if (r.foregroundServices) {
18304                foreground = 'S';
18305            } else {
18306                foreground = ' ';
18307            }
18308            String procState = ProcessList.makeProcStateString(r.curProcState);
18309            pw.print(prefix);
18310            pw.print(r.persistent ? persistentLabel : normalLabel);
18311            pw.print(" #");
18312            int num = (origList.size()-1)-list.get(i).second;
18313            if (num < 10) pw.print(' ');
18314            pw.print(num);
18315            pw.print(": ");
18316            pw.print(oomAdj);
18317            pw.print(' ');
18318            pw.print(schedGroup);
18319            pw.print('/');
18320            pw.print(foreground);
18321            pw.print('/');
18322            pw.print(procState);
18323            pw.print(" trm:");
18324            if (r.trimMemoryLevel < 10) pw.print(' ');
18325            pw.print(r.trimMemoryLevel);
18326            pw.print(' ');
18327            pw.print(r.toShortString());
18328            pw.print(" (");
18329            pw.print(r.adjType);
18330            pw.println(')');
18331            if (r.adjSource != null || r.adjTarget != null) {
18332                pw.print(prefix);
18333                pw.print("    ");
18334                if (r.adjTarget instanceof ComponentName) {
18335                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
18336                } else if (r.adjTarget != null) {
18337                    pw.print(r.adjTarget.toString());
18338                } else {
18339                    pw.print("{null}");
18340                }
18341                pw.print("<=");
18342                if (r.adjSource instanceof ProcessRecord) {
18343                    pw.print("Proc{");
18344                    pw.print(((ProcessRecord)r.adjSource).toShortString());
18345                    pw.println("}");
18346                } else if (r.adjSource != null) {
18347                    pw.println(r.adjSource.toString());
18348                } else {
18349                    pw.println("{null}");
18350                }
18351            }
18352            if (inclDetails) {
18353                pw.print(prefix);
18354                pw.print("    ");
18355                pw.print("oom: max="); pw.print(r.maxAdj);
18356                pw.print(" curRaw="); pw.print(r.curRawAdj);
18357                pw.print(" setRaw="); pw.print(r.setRawAdj);
18358                pw.print(" cur="); pw.print(r.curAdj);
18359                pw.print(" set="); pw.println(r.setAdj);
18360                pw.print(prefix);
18361                pw.print("    ");
18362                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
18363                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
18364                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
18365                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
18366                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
18367                pw.println();
18368                pw.print(prefix);
18369                pw.print("    ");
18370                pw.print("cached="); pw.print(r.cached);
18371                pw.print(" empty="); pw.print(r.empty);
18372                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
18373
18374                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
18375                    if (r.lastCpuTime != 0) {
18376                        long timeUsed = r.curCpuTime - r.lastCpuTime;
18377                        pw.print(prefix);
18378                        pw.print("    ");
18379                        pw.print("run cpu over ");
18380                        TimeUtils.formatDuration(uptimeSince, pw);
18381                        pw.print(" used ");
18382                        TimeUtils.formatDuration(timeUsed, pw);
18383                        pw.print(" (");
18384                        pw.print((timeUsed*100)/uptimeSince);
18385                        pw.println("%)");
18386                    }
18387                }
18388            }
18389        }
18390        return true;
18391    }
18392
18393    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
18394            String[] args) {
18395        ArrayList<ProcessRecord> procs;
18396        synchronized (this) {
18397            if (args != null && args.length > start
18398                    && args[start].charAt(0) != '-') {
18399                procs = new ArrayList<ProcessRecord>();
18400                int pid = -1;
18401                try {
18402                    pid = Integer.parseInt(args[start]);
18403                } catch (NumberFormatException e) {
18404                }
18405                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18406                    ProcessRecord proc = mLruProcesses.get(i);
18407                    if (proc.pid > 0 && proc.pid == pid) {
18408                        procs.add(proc);
18409                    } else if (allPkgs && proc.pkgList != null
18410                            && proc.pkgList.containsKey(args[start])) {
18411                        procs.add(proc);
18412                    } else if (proc.processName.equals(args[start])) {
18413                        procs.add(proc);
18414                    }
18415                }
18416                if (procs.size() <= 0) {
18417                    return null;
18418                }
18419            } else {
18420                procs = new ArrayList<ProcessRecord>(mLruProcesses);
18421            }
18422        }
18423        return procs;
18424    }
18425
18426    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
18427            PrintWriter pw, String[] args) {
18428        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18429        if (procs == null) {
18430            pw.println("No process found for: " + args[0]);
18431            return;
18432        }
18433
18434        long uptime = SystemClock.uptimeMillis();
18435        long realtime = SystemClock.elapsedRealtime();
18436        pw.println("Applications Graphics Acceleration Info:");
18437        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18438
18439        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18440            ProcessRecord r = procs.get(i);
18441            if (r.thread != null) {
18442                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
18443                pw.flush();
18444                try {
18445                    TransferPipe tp = new TransferPipe();
18446                    try {
18447                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
18448                        tp.go(fd);
18449                    } finally {
18450                        tp.kill();
18451                    }
18452                } catch (IOException e) {
18453                    pw.println("Failure while dumping the app: " + r);
18454                    pw.flush();
18455                } catch (RemoteException e) {
18456                    pw.println("Got a RemoteException while dumping the app " + r);
18457                    pw.flush();
18458                }
18459            }
18460        }
18461    }
18462
18463    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
18464        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18465        if (procs == null) {
18466            pw.println("No process found for: " + args[0]);
18467            return;
18468        }
18469
18470        pw.println("Applications Database Info:");
18471
18472        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18473            ProcessRecord r = procs.get(i);
18474            if (r.thread != null) {
18475                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
18476                pw.flush();
18477                try {
18478                    TransferPipe tp = new TransferPipe();
18479                    try {
18480                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
18481                        tp.go(fd);
18482                    } finally {
18483                        tp.kill();
18484                    }
18485                } catch (IOException e) {
18486                    pw.println("Failure while dumping the app: " + r);
18487                    pw.flush();
18488                } catch (RemoteException e) {
18489                    pw.println("Got a RemoteException while dumping the app " + r);
18490                    pw.flush();
18491                }
18492            }
18493        }
18494    }
18495
18496    final static class MemItem {
18497        final boolean isProc;
18498        final String label;
18499        final String shortLabel;
18500        final long pss;
18501        final long swapPss;
18502        final int id;
18503        final boolean hasActivities;
18504        ArrayList<MemItem> subitems;
18505
18506        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
18507                boolean _hasActivities) {
18508            isProc = true;
18509            label = _label;
18510            shortLabel = _shortLabel;
18511            pss = _pss;
18512            swapPss = _swapPss;
18513            id = _id;
18514            hasActivities = _hasActivities;
18515        }
18516
18517        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
18518            isProc = false;
18519            label = _label;
18520            shortLabel = _shortLabel;
18521            pss = _pss;
18522            swapPss = _swapPss;
18523            id = _id;
18524            hasActivities = false;
18525        }
18526    }
18527
18528    private static void sortMemItems(List<MemItem> items) {
18529        Collections.sort(items, new Comparator<MemItem>() {
18530            @Override
18531            public int compare(MemItem lhs, MemItem rhs) {
18532                if (lhs.pss < rhs.pss) {
18533                    return 1;
18534                } else if (lhs.pss > rhs.pss) {
18535                    return -1;
18536                }
18537                return 0;
18538            }
18539        });
18540    }
18541
18542    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
18543            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
18544        if (sort && !isCompact) {
18545            sortMemItems(items);
18546        }
18547
18548        for (int i=0; i<items.size(); i++) {
18549            MemItem mi = items.get(i);
18550            if (!isCompact) {
18551                if (dumpSwapPss) {
18552                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
18553                            mi.label, stringifyKBSize(mi.swapPss));
18554                } else {
18555                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
18556                }
18557            } else if (mi.isProc) {
18558                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
18559                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
18560                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
18561                pw.println(mi.hasActivities ? ",a" : ",e");
18562            } else {
18563                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
18564                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
18565            }
18566            if (mi.subitems != null) {
18567                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
18568                        true, isCompact, dumpSwapPss);
18569            }
18570        }
18571    }
18572
18573    static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
18574            ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
18575        if (sort) {
18576            sortMemItems(items);
18577        }
18578
18579        for (int i=0; i<items.size(); i++) {
18580            MemItem mi = items.get(i);
18581            final long token = proto.start(fieldId);
18582
18583            proto.write(MemInfoDumpProto.MemItem.TAG, tag);
18584            proto.write(MemInfoDumpProto.MemItem.LABEL, mi.shortLabel);
18585            proto.write(MemInfoDumpProto.MemItem.IS_PROC, mi.isProc);
18586            proto.write(MemInfoDumpProto.MemItem.ID, mi.id);
18587            proto.write(MemInfoDumpProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
18588            proto.write(MemInfoDumpProto.MemItem.PSS_KB, mi.pss);
18589            if (dumpSwapPss) {
18590                proto.write(MemInfoDumpProto.MemItem.SWAP_PSS_KB, mi.swapPss);
18591            }
18592            if (mi.subitems != null) {
18593                dumpMemItems(proto, MemInfoDumpProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
18594                        true, dumpSwapPss);
18595            }
18596            proto.end(token);
18597        }
18598    }
18599
18600    // These are in KB.
18601    static final long[] DUMP_MEM_BUCKETS = new long[] {
18602        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
18603        120*1024, 160*1024, 200*1024,
18604        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
18605        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
18606    };
18607
18608    static final void appendMemBucket(StringBuilder out, long memKB, String label,
18609            boolean stackLike) {
18610        int start = label.lastIndexOf('.');
18611        if (start >= 0) start++;
18612        else start = 0;
18613        int end = label.length();
18614        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
18615            if (DUMP_MEM_BUCKETS[i] >= memKB) {
18616                long bucket = DUMP_MEM_BUCKETS[i]/1024;
18617                out.append(bucket);
18618                out.append(stackLike ? "MB." : "MB ");
18619                out.append(label, start, end);
18620                return;
18621            }
18622        }
18623        out.append(memKB/1024);
18624        out.append(stackLike ? "MB." : "MB ");
18625        out.append(label, start, end);
18626    }
18627
18628    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
18629            ProcessList.NATIVE_ADJ,
18630            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
18631            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
18632            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
18633            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
18634            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
18635            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
18636    };
18637    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
18638            "Native",
18639            "System", "Persistent", "Persistent Service", "Foreground",
18640            "Visible", "Perceptible",
18641            "Heavy Weight", "Backup",
18642            "A Services", "Home",
18643            "Previous", "B Services", "Cached"
18644    };
18645    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
18646            "native",
18647            "sys", "pers", "persvc", "fore",
18648            "vis", "percept",
18649            "heavy", "backup",
18650            "servicea", "home",
18651            "prev", "serviceb", "cached"
18652    };
18653
18654    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
18655            long realtime, boolean isCheckinRequest, boolean isCompact) {
18656        if (isCompact) {
18657            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
18658        }
18659        if (isCheckinRequest || isCompact) {
18660            // short checkin version
18661            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
18662        } else {
18663            pw.println("Applications Memory Usage (in Kilobytes):");
18664            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18665        }
18666    }
18667
18668    private static final int KSM_SHARED = 0;
18669    private static final int KSM_SHARING = 1;
18670    private static final int KSM_UNSHARED = 2;
18671    private static final int KSM_VOLATILE = 3;
18672
18673    private final long[] getKsmInfo() {
18674        long[] longOut = new long[4];
18675        final int[] SINGLE_LONG_FORMAT = new int[] {
18676            PROC_SPACE_TERM| PROC_OUT_LONG
18677        };
18678        long[] longTmp = new long[1];
18679        readProcFile("/sys/kernel/mm/ksm/pages_shared",
18680                SINGLE_LONG_FORMAT, null, longTmp, null);
18681        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18682        longTmp[0] = 0;
18683        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
18684                SINGLE_LONG_FORMAT, null, longTmp, null);
18685        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18686        longTmp[0] = 0;
18687        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
18688                SINGLE_LONG_FORMAT, null, longTmp, null);
18689        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18690        longTmp[0] = 0;
18691        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
18692                SINGLE_LONG_FORMAT, null, longTmp, null);
18693        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18694        return longOut;
18695    }
18696
18697    private static String stringifySize(long size, int order) {
18698        Locale locale = Locale.US;
18699        switch (order) {
18700            case 1:
18701                return String.format(locale, "%,13d", size);
18702            case 1024:
18703                return String.format(locale, "%,9dK", size / 1024);
18704            case 1024 * 1024:
18705                return String.format(locale, "%,5dM", size / 1024 / 1024);
18706            case 1024 * 1024 * 1024:
18707                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
18708            default:
18709                throw new IllegalArgumentException("Invalid size order");
18710        }
18711    }
18712
18713    private static String stringifyKBSize(long size) {
18714        return stringifySize(size * 1024, 1024);
18715    }
18716
18717    // Update this version number if you change the 'compact' format.
18718    private static final int MEMINFO_COMPACT_VERSION = 1;
18719
18720    private static class MemoryUsageDumpOptions {
18721        boolean dumpDetails;
18722        boolean dumpFullDetails;
18723        boolean dumpDalvik;
18724        boolean dumpSummaryOnly;
18725        boolean dumpUnreachable;
18726        boolean oomOnly;
18727        boolean isCompact;
18728        boolean localOnly;
18729        boolean packages;
18730        boolean isCheckinRequest;
18731        boolean dumpSwapPss;
18732        boolean dumpProto;
18733    }
18734
18735    final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18736            String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) {
18737        MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions();
18738        opts.dumpDetails = false;
18739        opts.dumpFullDetails = false;
18740        opts.dumpDalvik = false;
18741        opts.dumpSummaryOnly = false;
18742        opts.dumpUnreachable = false;
18743        opts.oomOnly = false;
18744        opts.isCompact = false;
18745        opts.localOnly = false;
18746        opts.packages = false;
18747        opts.isCheckinRequest = false;
18748        opts.dumpSwapPss = false;
18749        opts.dumpProto = asProto;
18750
18751        int opti = 0;
18752        while (opti < args.length) {
18753            String opt = args[opti];
18754            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18755                break;
18756            }
18757            opti++;
18758            if ("-a".equals(opt)) {
18759                opts.dumpDetails = true;
18760                opts.dumpFullDetails = true;
18761                opts.dumpDalvik = true;
18762                opts.dumpSwapPss = true;
18763            } else if ("-d".equals(opt)) {
18764                opts.dumpDalvik = true;
18765            } else if ("-c".equals(opt)) {
18766                opts.isCompact = true;
18767            } else if ("-s".equals(opt)) {
18768                opts.dumpDetails = true;
18769                opts.dumpSummaryOnly = true;
18770            } else if ("-S".equals(opt)) {
18771                opts.dumpSwapPss = true;
18772            } else if ("--unreachable".equals(opt)) {
18773                opts.dumpUnreachable = true;
18774            } else if ("--oom".equals(opt)) {
18775                opts.oomOnly = true;
18776            } else if ("--local".equals(opt)) {
18777                opts.localOnly = true;
18778            } else if ("--package".equals(opt)) {
18779                opts.packages = true;
18780            } else if ("--checkin".equals(opt)) {
18781                opts.isCheckinRequest = true;
18782            } else if ("--proto".equals(opt)) {
18783                opts.dumpProto = true;
18784
18785            } else if ("-h".equals(opt)) {
18786                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
18787                pw.println("  -a: include all available information for each process.");
18788                pw.println("  -d: include dalvik details.");
18789                pw.println("  -c: dump in a compact machine-parseable representation.");
18790                pw.println("  -s: dump only summary of application memory usage.");
18791                pw.println("  -S: dump also SwapPss.");
18792                pw.println("  --oom: only show processes organized by oom adj.");
18793                pw.println("  --local: only collect details locally, don't call process.");
18794                pw.println("  --package: interpret process arg as package, dumping all");
18795                pw.println("             processes that have loaded that package.");
18796                pw.println("  --checkin: dump data for a checkin");
18797                pw.println("  --proto: dump data to proto");
18798                pw.println("If [process] is specified it can be the name or ");
18799                pw.println("pid of a specific process to dump.");
18800                return;
18801            } else {
18802                pw.println("Unknown argument: " + opt + "; use -h for help");
18803            }
18804        }
18805
18806        String[] innerArgs = new String[args.length-opti];
18807        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
18808
18809        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
18810        if (opts.dumpProto) {
18811            dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
18812        } else {
18813            dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
18814        }
18815    }
18816
18817    private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18818            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18819            ArrayList<ProcessRecord> procs, PrintWriter categoryPw) {
18820        long uptime = SystemClock.uptimeMillis();
18821        long realtime = SystemClock.elapsedRealtime();
18822        final long[] tmpLong = new long[1];
18823
18824        if (procs == null) {
18825            // No Java processes.  Maybe they want to print a native process.
18826            String proc = "N/A";
18827            if (innerArgs.length > 0) {
18828                proc = innerArgs[0];
18829                if (proc.charAt(0) != '-') {
18830                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
18831                            = new ArrayList<ProcessCpuTracker.Stats>();
18832                    updateCpuStatsNow();
18833                    int findPid = -1;
18834                    try {
18835                        findPid = Integer.parseInt(innerArgs[0]);
18836                    } catch (NumberFormatException e) {
18837                    }
18838                    synchronized (mProcessCpuTracker) {
18839                        final int N = mProcessCpuTracker.countStats();
18840                        for (int i=0; i<N; i++) {
18841                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18842                            if (st.pid == findPid || (st.baseName != null
18843                                    && st.baseName.equals(innerArgs[0]))) {
18844                                nativeProcs.add(st);
18845                            }
18846                        }
18847                    }
18848                    if (nativeProcs.size() > 0) {
18849                        dumpApplicationMemoryUsageHeader(pw, uptime, realtime,
18850                                opts.isCheckinRequest, opts.isCompact);
18851                        Debug.MemoryInfo mi = null;
18852                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18853                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18854                            final int pid = r.pid;
18855                            if (!opts.isCheckinRequest && opts.dumpDetails) {
18856                                pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
18857                            }
18858                            if (mi == null) {
18859                                mi = new Debug.MemoryInfo();
18860                            }
18861                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18862                                Debug.getMemoryInfo(pid, mi);
18863                            } else {
18864                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18865                                mi.dalvikPrivateDirty = (int)tmpLong[0];
18866                            }
18867                            ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest,
18868                                    opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18869                                    pid, r.baseName, 0, 0, 0, 0, 0, 0);
18870                            if (opts.isCheckinRequest) {
18871                                pw.println();
18872                            }
18873                        }
18874                        return;
18875                    }
18876                }
18877            }
18878            pw.println("No process found for: " + proc);
18879            return;
18880        }
18881
18882        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18883            opts.dumpDetails = true;
18884        }
18885
18886        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
18887
18888        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18889        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18890        long nativePss = 0;
18891        long nativeSwapPss = 0;
18892        long dalvikPss = 0;
18893        long dalvikSwapPss = 0;
18894        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18895                EmptyArray.LONG;
18896        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18897                EmptyArray.LONG;
18898        long otherPss = 0;
18899        long otherSwapPss = 0;
18900        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18901        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18902
18903        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18904        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18905        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18906                new ArrayList[DUMP_MEM_OOM_LABEL.length];
18907
18908        long totalPss = 0;
18909        long totalSwapPss = 0;
18910        long cachedPss = 0;
18911        long cachedSwapPss = 0;
18912        boolean hasSwapPss = false;
18913
18914        Debug.MemoryInfo mi = null;
18915        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18916            final ProcessRecord r = procs.get(i);
18917            final IApplicationThread thread;
18918            final int pid;
18919            final int oomAdj;
18920            final boolean hasActivities;
18921            synchronized (this) {
18922                thread = r.thread;
18923                pid = r.pid;
18924                oomAdj = r.getSetAdjWithServices();
18925                hasActivities = r.activities.size() > 0;
18926            }
18927            if (thread != null) {
18928                if (!opts.isCheckinRequest && opts.dumpDetails) {
18929                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
18930                }
18931                if (mi == null) {
18932                    mi = new Debug.MemoryInfo();
18933                }
18934                final int reportType;
18935                final long startTime;
18936                final long endTime;
18937                if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18938                    reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
18939                    startTime = SystemClock.currentThreadTimeMillis();
18940                    Debug.getMemoryInfo(pid, mi);
18941                    endTime = SystemClock.currentThreadTimeMillis();
18942                    hasSwapPss = mi.hasSwappedOutPss;
18943                } else {
18944                    reportType = ProcessStats.ADD_PSS_EXTERNAL;
18945                    startTime = SystemClock.currentThreadTimeMillis();
18946                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18947                    endTime = SystemClock.currentThreadTimeMillis();
18948                    mi.dalvikPrivateDirty = (int)tmpLong[0];
18949                }
18950                if (opts.dumpDetails) {
18951                    if (opts.localOnly) {
18952                        ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
18953                                opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
18954                        if (opts.isCheckinRequest) {
18955                            pw.println();
18956                        }
18957                    } else {
18958                        pw.flush();
18959                        try {
18960                            TransferPipe tp = new TransferPipe();
18961                            try {
18962                                thread.dumpMemInfo(tp.getWriteFd(),
18963                                        mi, opts.isCheckinRequest, opts.dumpFullDetails,
18964                                        opts.dumpDalvik, opts.dumpSummaryOnly, opts.dumpUnreachable, innerArgs);
18965                                tp.go(fd, opts.dumpUnreachable ? 30000 : 5000);
18966                            } finally {
18967                                tp.kill();
18968                            }
18969                        } catch (IOException e) {
18970                            if (!opts.isCheckinRequest) {
18971                                pw.println("Got IoException! " + e);
18972                                pw.flush();
18973                            }
18974                        } catch (RemoteException e) {
18975                            if (!opts.isCheckinRequest) {
18976                                pw.println("Got RemoteException! " + e);
18977                                pw.flush();
18978                            }
18979                        }
18980                    }
18981                }
18982
18983                final long myTotalPss = mi.getTotalPss();
18984                final long myTotalUss = mi.getTotalUss();
18985                final long myTotalRss = mi.getTotalRss();
18986                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18987
18988                synchronized (this) {
18989                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
18990                        // Record this for posterity if the process has been stable.
18991                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
18992                                reportType, endTime-startTime, r.pkgList);
18993                    }
18994                }
18995
18996                if (!opts.isCheckinRequest && mi != null) {
18997                    totalPss += myTotalPss;
18998                    totalSwapPss += myTotalSwapPss;
18999                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
19000                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
19001                            myTotalSwapPss, pid, hasActivities);
19002                    procMems.add(pssItem);
19003                    procMemsMap.put(pid, pssItem);
19004
19005                    nativePss += mi.nativePss;
19006                    nativeSwapPss += mi.nativeSwappedOutPss;
19007                    dalvikPss += mi.dalvikPss;
19008                    dalvikSwapPss += mi.dalvikSwappedOutPss;
19009                    for (int j=0; j<dalvikSubitemPss.length; j++) {
19010                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19011                        dalvikSubitemSwapPss[j] +=
19012                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19013                    }
19014                    otherPss += mi.otherPss;
19015                    otherSwapPss += mi.otherSwappedOutPss;
19016                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19017                        long mem = mi.getOtherPss(j);
19018                        miscPss[j] += mem;
19019                        otherPss -= mem;
19020                        mem = mi.getOtherSwappedOutPss(j);
19021                        miscSwapPss[j] += mem;
19022                        otherSwapPss -= mem;
19023                    }
19024
19025                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19026                        cachedPss += myTotalPss;
19027                        cachedSwapPss += myTotalSwapPss;
19028                    }
19029
19030                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
19031                        if (oomIndex == (oomPss.length - 1)
19032                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
19033                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
19034                            oomPss[oomIndex] += myTotalPss;
19035                            oomSwapPss[oomIndex] += myTotalSwapPss;
19036                            if (oomProcs[oomIndex] == null) {
19037                                oomProcs[oomIndex] = new ArrayList<MemItem>();
19038                            }
19039                            oomProcs[oomIndex].add(pssItem);
19040                            break;
19041                        }
19042                    }
19043                }
19044            }
19045        }
19046
19047        long nativeProcTotalPss = 0;
19048
19049        if (!opts.isCheckinRequest && procs.size() > 1 && !opts.packages) {
19050            // If we are showing aggregations, also look for native processes to
19051            // include so that our aggregations are more accurate.
19052            updateCpuStatsNow();
19053            mi = null;
19054            synchronized (mProcessCpuTracker) {
19055                final int N = mProcessCpuTracker.countStats();
19056                for (int i=0; i<N; i++) {
19057                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19058                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
19059                        if (mi == null) {
19060                            mi = new Debug.MemoryInfo();
19061                        }
19062                        if (!brief && !opts.oomOnly) {
19063                            Debug.getMemoryInfo(st.pid, mi);
19064                        } else {
19065                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19066                            mi.nativePrivateDirty = (int)tmpLong[0];
19067                        }
19068
19069                        final long myTotalPss = mi.getTotalPss();
19070                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19071                        totalPss += myTotalPss;
19072                        totalSwapPss += myTotalSwapPss;
19073                        nativeProcTotalPss += myTotalPss;
19074
19075                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19076                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19077                        procMems.add(pssItem);
19078
19079                        nativePss += mi.nativePss;
19080                        nativeSwapPss += mi.nativeSwappedOutPss;
19081                        dalvikPss += mi.dalvikPss;
19082                        dalvikSwapPss += mi.dalvikSwappedOutPss;
19083                        for (int j=0; j<dalvikSubitemPss.length; j++) {
19084                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19085                            dalvikSubitemSwapPss[j] +=
19086                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19087                        }
19088                        otherPss += mi.otherPss;
19089                        otherSwapPss += mi.otherSwappedOutPss;
19090                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19091                            long mem = mi.getOtherPss(j);
19092                            miscPss[j] += mem;
19093                            otherPss -= mem;
19094                            mem = mi.getOtherSwappedOutPss(j);
19095                            miscSwapPss[j] += mem;
19096                            otherSwapPss -= mem;
19097                        }
19098                        oomPss[0] += myTotalPss;
19099                        oomSwapPss[0] += myTotalSwapPss;
19100                        if (oomProcs[0] == null) {
19101                            oomProcs[0] = new ArrayList<MemItem>();
19102                        }
19103                        oomProcs[0].add(pssItem);
19104                    }
19105                }
19106            }
19107
19108            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19109
19110            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19111            final int dalvikId = -2;
19112            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19113            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19114            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19115                String label = Debug.MemoryInfo.getOtherLabel(j);
19116                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19117            }
19118            if (dalvikSubitemPss.length > 0) {
19119                // Add dalvik subitems.
19120                for (MemItem memItem : catMems) {
19121                    int memItemStart = 0, memItemEnd = 0;
19122                    if (memItem.id == dalvikId) {
19123                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19124                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19125                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19126                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19127                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19128                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19129                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19130                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19131                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19132                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19133                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19134                    } else {
19135                        continue;  // No subitems, continue.
19136                    }
19137                    memItem.subitems = new ArrayList<MemItem>();
19138                    for (int j=memItemStart; j<=memItemEnd; j++) {
19139                        final String name = Debug.MemoryInfo.getOtherLabel(
19140                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
19141                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19142                                dalvikSubitemSwapPss[j], j));
19143                    }
19144                }
19145            }
19146
19147            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19148            for (int j=0; j<oomPss.length; j++) {
19149                if (oomPss[j] != 0) {
19150                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19151                            : DUMP_MEM_OOM_LABEL[j];
19152                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19153                            DUMP_MEM_OOM_ADJ[j]);
19154                    item.subitems = oomProcs[j];
19155                    oomMems.add(item);
19156                }
19157            }
19158
19159            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19160            if (!brief && !opts.oomOnly && !opts.isCompact) {
19161                pw.println();
19162                pw.println("Total PSS by process:");
19163                dumpMemItems(pw, "  ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
19164                pw.println();
19165            }
19166            if (!opts.isCompact) {
19167                pw.println("Total PSS by OOM adjustment:");
19168            }
19169            dumpMemItems(pw, "  ", "oom", oomMems, false, opts.isCompact, opts.dumpSwapPss);
19170            if (!brief && !opts.oomOnly) {
19171                PrintWriter out = categoryPw != null ? categoryPw : pw;
19172                if (!opts.isCompact) {
19173                    out.println();
19174                    out.println("Total PSS by category:");
19175                }
19176                dumpMemItems(out, "  ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
19177            }
19178            if (!opts.isCompact) {
19179                pw.println();
19180            }
19181            MemInfoReader memInfo = new MemInfoReader();
19182            memInfo.readMemInfo();
19183            if (nativeProcTotalPss > 0) {
19184                synchronized (this) {
19185                    final long cachedKb = memInfo.getCachedSizeKb();
19186                    final long freeKb = memInfo.getFreeSizeKb();
19187                    final long zramKb = memInfo.getZramTotalSizeKb();
19188                    final long kernelKb = memInfo.getKernelUsedSizeKb();
19189                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19190                            kernelKb*1024, nativeProcTotalPss*1024);
19191                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19192                            nativeProcTotalPss);
19193                }
19194            }
19195            if (!brief) {
19196                if (!opts.isCompact) {
19197                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
19198                    pw.print(" (status ");
19199                    switch (mLastMemoryLevel) {
19200                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
19201                            pw.println("normal)");
19202                            break;
19203                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
19204                            pw.println("moderate)");
19205                            break;
19206                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
19207                            pw.println("low)");
19208                            break;
19209                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19210                            pw.println("critical)");
19211                            break;
19212                        default:
19213                            pw.print(mLastMemoryLevel);
19214                            pw.println(")");
19215                            break;
19216                    }
19217                    pw.print(" Free RAM: ");
19218                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19219                            + memInfo.getFreeSizeKb()));
19220                    pw.print(" (");
19221                    pw.print(stringifyKBSize(cachedPss));
19222                    pw.print(" cached pss + ");
19223                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
19224                    pw.print(" cached kernel + ");
19225                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
19226                    pw.println(" free)");
19227                } else {
19228                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
19229                    pw.print(cachedPss + memInfo.getCachedSizeKb()
19230                            + memInfo.getFreeSizeKb()); pw.print(",");
19231                    pw.println(totalPss - cachedPss);
19232                }
19233            }
19234            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19235                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19236                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19237            if (!opts.isCompact) {
19238                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
19239                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
19240                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
19241                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
19242                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
19243            } else {
19244                pw.print("lostram,"); pw.println(lostRAM);
19245            }
19246            if (!brief) {
19247                if (memInfo.getZramTotalSizeKb() != 0) {
19248                    if (!opts.isCompact) {
19249                        pw.print("     ZRAM: ");
19250                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
19251                                pw.print(" physical used for ");
19252                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
19253                                        - memInfo.getSwapFreeSizeKb()));
19254                                pw.print(" in swap (");
19255                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
19256                                pw.println(" total swap)");
19257                    } else {
19258                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
19259                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
19260                                pw.println(memInfo.getSwapFreeSizeKb());
19261                    }
19262                }
19263                final long[] ksm = getKsmInfo();
19264                if (!opts.isCompact) {
19265                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
19266                            || ksm[KSM_VOLATILE] != 0) {
19267                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
19268                                pw.print(" saved from shared ");
19269                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
19270                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
19271                                pw.print(" unshared; ");
19272                                pw.print(stringifyKBSize(
19273                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
19274                    }
19275                    pw.print("   Tuning: ");
19276                    pw.print(ActivityManager.staticGetMemoryClass());
19277                    pw.print(" (large ");
19278                    pw.print(ActivityManager.staticGetLargeMemoryClass());
19279                    pw.print("), oom ");
19280                    pw.print(stringifySize(
19281                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
19282                    pw.print(", restore limit ");
19283                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
19284                    if (ActivityManager.isLowRamDeviceStatic()) {
19285                        pw.print(" (low-ram)");
19286                    }
19287                    if (ActivityManager.isHighEndGfx()) {
19288                        pw.print(" (high-end-gfx)");
19289                    }
19290                    pw.println();
19291                } else {
19292                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
19293                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
19294                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
19295                    pw.print("tuning,");
19296                    pw.print(ActivityManager.staticGetMemoryClass());
19297                    pw.print(',');
19298                    pw.print(ActivityManager.staticGetLargeMemoryClass());
19299                    pw.print(',');
19300                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
19301                    if (ActivityManager.isLowRamDeviceStatic()) {
19302                        pw.print(",low-ram");
19303                    }
19304                    if (ActivityManager.isHighEndGfx()) {
19305                        pw.print(",high-end-gfx");
19306                    }
19307                    pw.println();
19308                }
19309            }
19310        }
19311    }
19312
19313    private final void dumpApplicationMemoryUsage(FileDescriptor fd,
19314            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
19315            ArrayList<ProcessRecord> procs) {
19316        final long uptimeMs = SystemClock.uptimeMillis();
19317        final long realtimeMs = SystemClock.elapsedRealtime();
19318        final long[] tmpLong = new long[1];
19319
19320        if (procs == null) {
19321            // No Java processes.  Maybe they want to print a native process.
19322            String proc = "N/A";
19323            if (innerArgs.length > 0) {
19324                proc = innerArgs[0];
19325                if (proc.charAt(0) != '-') {
19326                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
19327                            = new ArrayList<ProcessCpuTracker.Stats>();
19328                    updateCpuStatsNow();
19329                    int findPid = -1;
19330                    try {
19331                        findPid = Integer.parseInt(innerArgs[0]);
19332                    } catch (NumberFormatException e) {
19333                    }
19334                    synchronized (mProcessCpuTracker) {
19335                        final int N = mProcessCpuTracker.countStats();
19336                        for (int i=0; i<N; i++) {
19337                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19338                            if (st.pid == findPid || (st.baseName != null
19339                                    && st.baseName.equals(innerArgs[0]))) {
19340                                nativeProcs.add(st);
19341                            }
19342                        }
19343                    }
19344                    if (nativeProcs.size() > 0) {
19345                        ProtoOutputStream proto = new ProtoOutputStream(fd);
19346
19347                        proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
19348                        proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
19349                        Debug.MemoryInfo mi = null;
19350                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
19351                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
19352                            final int pid = r.pid;
19353                            final long nToken = proto.start(MemInfoDumpProto.NATIVE_PROCESSES);
19354
19355                            proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
19356                            proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName);
19357
19358                            if (mi == null) {
19359                                mi = new Debug.MemoryInfo();
19360                            }
19361                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19362                                Debug.getMemoryInfo(pid, mi);
19363                            } else {
19364                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
19365                                mi.dalvikPrivateDirty = (int)tmpLong[0];
19366                            }
19367                            ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19368                                    opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19369
19370                            proto.end(nToken);
19371                        }
19372
19373                        proto.flush();
19374                        return;
19375                    }
19376                }
19377            }
19378            Log.d(TAG, "No process found for: " + innerArgs[0]);
19379            return;
19380        }
19381
19382        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
19383            opts.dumpDetails = true;
19384        }
19385
19386        ProtoOutputStream proto = new ProtoOutputStream(fd);
19387
19388        proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
19389        proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
19390
19391        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
19392        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
19393        long nativePss = 0;
19394        long nativeSwapPss = 0;
19395        long dalvikPss = 0;
19396        long dalvikSwapPss = 0;
19397        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19398                EmptyArray.LONG;
19399        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19400                EmptyArray.LONG;
19401        long otherPss = 0;
19402        long otherSwapPss = 0;
19403        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19404        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19405
19406        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19407        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19408        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
19409                new ArrayList[DUMP_MEM_OOM_LABEL.length];
19410
19411        long totalPss = 0;
19412        long totalSwapPss = 0;
19413        long cachedPss = 0;
19414        long cachedSwapPss = 0;
19415        boolean hasSwapPss = false;
19416
19417        Debug.MemoryInfo mi = null;
19418        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
19419            final ProcessRecord r = procs.get(i);
19420            final IApplicationThread thread;
19421            final int pid;
19422            final int oomAdj;
19423            final boolean hasActivities;
19424            synchronized (this) {
19425                thread = r.thread;
19426                pid = r.pid;
19427                oomAdj = r.getSetAdjWithServices();
19428                hasActivities = r.activities.size() > 0;
19429            }
19430            if (thread == null) {
19431                continue;
19432            }
19433            if (mi == null) {
19434                mi = new Debug.MemoryInfo();
19435            }
19436            final int reportType;
19437            final long startTime;
19438            final long endTime;
19439            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19440                reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
19441                startTime = SystemClock.currentThreadTimeMillis();
19442                Debug.getMemoryInfo(pid, mi);
19443                endTime = SystemClock.currentThreadTimeMillis();
19444                hasSwapPss = mi.hasSwappedOutPss;
19445            } else {
19446                reportType = ProcessStats.ADD_PSS_EXTERNAL;
19447                startTime = SystemClock.currentThreadTimeMillis();
19448                mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
19449                endTime = SystemClock.currentThreadTimeMillis();
19450                mi.dalvikPrivateDirty = (int) tmpLong[0];
19451            }
19452            if (opts.dumpDetails) {
19453                if (opts.localOnly) {
19454                    final long aToken = proto.start(MemInfoDumpProto.APP_PROCESSES);
19455                    final long mToken = proto.start(MemInfoDumpProto.AppData.PROCESS_MEMORY);
19456                    proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
19457                    proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.processName);
19458                    ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19459                            opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19460                    proto.end(mToken);
19461                    proto.end(aToken);
19462                } else {
19463                    try {
19464                        ByteTransferPipe tp = new ByteTransferPipe();
19465                        try {
19466                            thread.dumpMemInfoProto(tp.getWriteFd(),
19467                                mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
19468                                opts.dumpUnreachable, innerArgs);
19469                            proto.write(MemInfoDumpProto.APP_PROCESSES, tp.get());
19470                        } finally {
19471                            tp.kill();
19472                        }
19473                    } catch (IOException e) {
19474                        Log.e(TAG, "Got IOException!", e);
19475                    } catch (RemoteException e) {
19476                        Log.e(TAG, "Got RemoteException!", e);
19477                    }
19478                }
19479            }
19480
19481            final long myTotalPss = mi.getTotalPss();
19482            final long myTotalUss = mi.getTotalUss();
19483            final long myTotalRss = mi.getTotalRss();
19484            final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19485
19486            synchronized (this) {
19487                if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
19488                    // Record this for posterity if the process has been stable.
19489                    r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
19490                            reportType, endTime-startTime, r.pkgList);
19491                }
19492            }
19493
19494            if (!opts.isCheckinRequest && mi != null) {
19495                totalPss += myTotalPss;
19496                totalSwapPss += myTotalSwapPss;
19497                MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
19498                        (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
19499                        myTotalSwapPss, pid, hasActivities);
19500                procMems.add(pssItem);
19501                procMemsMap.put(pid, pssItem);
19502
19503                nativePss += mi.nativePss;
19504                nativeSwapPss += mi.nativeSwappedOutPss;
19505                dalvikPss += mi.dalvikPss;
19506                dalvikSwapPss += mi.dalvikSwappedOutPss;
19507                for (int j=0; j<dalvikSubitemPss.length; j++) {
19508                    dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19509                    dalvikSubitemSwapPss[j] +=
19510                            mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19511                }
19512                otherPss += mi.otherPss;
19513                otherSwapPss += mi.otherSwappedOutPss;
19514                for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19515                    long mem = mi.getOtherPss(j);
19516                    miscPss[j] += mem;
19517                    otherPss -= mem;
19518                    mem = mi.getOtherSwappedOutPss(j);
19519                    miscSwapPss[j] += mem;
19520                    otherSwapPss -= mem;
19521                }
19522
19523                if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19524                    cachedPss += myTotalPss;
19525                    cachedSwapPss += myTotalSwapPss;
19526                }
19527
19528                for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
19529                    if (oomIndex == (oomPss.length - 1)
19530                            || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
19531                                    && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
19532                        oomPss[oomIndex] += myTotalPss;
19533                        oomSwapPss[oomIndex] += myTotalSwapPss;
19534                        if (oomProcs[oomIndex] == null) {
19535                            oomProcs[oomIndex] = new ArrayList<MemItem>();
19536                        }
19537                        oomProcs[oomIndex].add(pssItem);
19538                        break;
19539                    }
19540                }
19541            }
19542        }
19543
19544        long nativeProcTotalPss = 0;
19545
19546        if (procs.size() > 1 && !opts.packages) {
19547            // If we are showing aggregations, also look for native processes to
19548            // include so that our aggregations are more accurate.
19549            updateCpuStatsNow();
19550            mi = null;
19551            synchronized (mProcessCpuTracker) {
19552                final int N = mProcessCpuTracker.countStats();
19553                for (int i=0; i<N; i++) {
19554                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19555                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
19556                        if (mi == null) {
19557                            mi = new Debug.MemoryInfo();
19558                        }
19559                        if (!brief && !opts.oomOnly) {
19560                            Debug.getMemoryInfo(st.pid, mi);
19561                        } else {
19562                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19563                            mi.nativePrivateDirty = (int)tmpLong[0];
19564                        }
19565
19566                        final long myTotalPss = mi.getTotalPss();
19567                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19568                        totalPss += myTotalPss;
19569                        nativeProcTotalPss += myTotalPss;
19570
19571                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19572                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19573                        procMems.add(pssItem);
19574
19575                        nativePss += mi.nativePss;
19576                        nativeSwapPss += mi.nativeSwappedOutPss;
19577                        dalvikPss += mi.dalvikPss;
19578                        dalvikSwapPss += mi.dalvikSwappedOutPss;
19579                        for (int j=0; j<dalvikSubitemPss.length; j++) {
19580                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19581                            dalvikSubitemSwapPss[j] +=
19582                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19583                        }
19584                        otherPss += mi.otherPss;
19585                        otherSwapPss += mi.otherSwappedOutPss;
19586                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19587                            long mem = mi.getOtherPss(j);
19588                            miscPss[j] += mem;
19589                            otherPss -= mem;
19590                            mem = mi.getOtherSwappedOutPss(j);
19591                            miscSwapPss[j] += mem;
19592                            otherSwapPss -= mem;
19593                        }
19594                        oomPss[0] += myTotalPss;
19595                        oomSwapPss[0] += myTotalSwapPss;
19596                        if (oomProcs[0] == null) {
19597                            oomProcs[0] = new ArrayList<MemItem>();
19598                        }
19599                        oomProcs[0].add(pssItem);
19600                    }
19601                }
19602            }
19603
19604            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19605
19606            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19607            final int dalvikId = -2;
19608            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19609            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19610            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19611                String label = Debug.MemoryInfo.getOtherLabel(j);
19612                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19613            }
19614            if (dalvikSubitemPss.length > 0) {
19615                // Add dalvik subitems.
19616                for (MemItem memItem : catMems) {
19617                    int memItemStart = 0, memItemEnd = 0;
19618                    if (memItem.id == dalvikId) {
19619                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19620                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19621                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19622                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19623                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19624                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19625                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19626                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19627                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19628                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19629                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19630                    } else {
19631                        continue;  // No subitems, continue.
19632                    }
19633                    memItem.subitems = new ArrayList<MemItem>();
19634                    for (int j=memItemStart; j<=memItemEnd; j++) {
19635                        final String name = Debug.MemoryInfo.getOtherLabel(
19636                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
19637                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19638                                dalvikSubitemSwapPss[j], j));
19639                    }
19640                }
19641            }
19642
19643            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19644            for (int j=0; j<oomPss.length; j++) {
19645                if (oomPss[j] != 0) {
19646                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19647                            : DUMP_MEM_OOM_LABEL[j];
19648                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19649                            DUMP_MEM_OOM_ADJ[j]);
19650                    item.subitems = oomProcs[j];
19651                    oomMems.add(item);
19652                }
19653            }
19654
19655            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19656            if (!opts.oomOnly) {
19657                dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_PROCESS, "proc",
19658                        procMems, true, opts.dumpSwapPss);
19659            }
19660            dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
19661                    oomMems, false, opts.dumpSwapPss);
19662            if (!brief && !opts.oomOnly) {
19663                dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_CATEGORY, "cat",
19664                        catMems, true, opts.dumpSwapPss);
19665            }
19666            MemInfoReader memInfo = new MemInfoReader();
19667            memInfo.readMemInfo();
19668            if (nativeProcTotalPss > 0) {
19669                synchronized (this) {
19670                    final long cachedKb = memInfo.getCachedSizeKb();
19671                    final long freeKb = memInfo.getFreeSizeKb();
19672                    final long zramKb = memInfo.getZramTotalSizeKb();
19673                    final long kernelKb = memInfo.getKernelUsedSizeKb();
19674                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19675                            kernelKb*1024, nativeProcTotalPss*1024);
19676                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19677                            nativeProcTotalPss);
19678                }
19679            }
19680            if (!brief) {
19681                proto.write(MemInfoDumpProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
19682                proto.write(MemInfoDumpProto.STATUS, mLastMemoryLevel);
19683                proto.write(MemInfoDumpProto.CACHED_PSS_KB, cachedPss);
19684                proto.write(MemInfoDumpProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
19685                proto.write(MemInfoDumpProto.FREE_KB, memInfo.getFreeSizeKb());
19686            }
19687            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19688                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19689                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19690            proto.write(MemInfoDumpProto.USED_PSS_KB, totalPss - cachedPss);
19691            proto.write(MemInfoDumpProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
19692            proto.write(MemInfoDumpProto.LOST_RAM_KB, lostRAM);
19693            if (!brief) {
19694                if (memInfo.getZramTotalSizeKb() != 0) {
19695                    proto.write(MemInfoDumpProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
19696                    proto.write(MemInfoDumpProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
19697                            memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
19698                    proto.write(MemInfoDumpProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
19699                }
19700                final long[] ksm = getKsmInfo();
19701                proto.write(MemInfoDumpProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
19702                proto.write(MemInfoDumpProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
19703                proto.write(MemInfoDumpProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
19704                proto.write(MemInfoDumpProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
19705
19706                proto.write(MemInfoDumpProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
19707                proto.write(MemInfoDumpProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
19708                proto.write(MemInfoDumpProto.OOM_KB,
19709                        mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
19710                proto.write(MemInfoDumpProto.RESTORE_LIMIT_KB,
19711                        mProcessList.getCachedRestoreThresholdKb());
19712
19713                proto.write(MemInfoDumpProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
19714                proto.write(MemInfoDumpProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
19715            }
19716        }
19717
19718        proto.flush();
19719    }
19720
19721    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
19722            long memtrack, String name) {
19723        sb.append("  ");
19724        sb.append(ProcessList.makeOomAdjString(oomAdj));
19725        sb.append(' ');
19726        sb.append(ProcessList.makeProcStateString(procState));
19727        sb.append(' ');
19728        ProcessList.appendRamKb(sb, pss);
19729        sb.append(": ");
19730        sb.append(name);
19731        if (memtrack > 0) {
19732            sb.append(" (");
19733            sb.append(stringifyKBSize(memtrack));
19734            sb.append(" memtrack)");
19735        }
19736    }
19737
19738    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
19739        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
19740        sb.append(" (pid ");
19741        sb.append(mi.pid);
19742        sb.append(") ");
19743        sb.append(mi.adjType);
19744        sb.append('\n');
19745        if (mi.adjReason != null) {
19746            sb.append("                      ");
19747            sb.append(mi.adjReason);
19748            sb.append('\n');
19749        }
19750    }
19751
19752    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
19753        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
19754        for (int i=0, N=memInfos.size(); i<N; i++) {
19755            ProcessMemInfo mi = memInfos.get(i);
19756            infoMap.put(mi.pid, mi);
19757        }
19758        updateCpuStatsNow();
19759        long[] memtrackTmp = new long[1];
19760        final List<ProcessCpuTracker.Stats> stats;
19761        // Get a list of Stats that have vsize > 0
19762        synchronized (mProcessCpuTracker) {
19763            stats = mProcessCpuTracker.getStats((st) -> {
19764                return st.vsize > 0;
19765            });
19766        }
19767        final int statsCount = stats.size();
19768        for (int i = 0; i < statsCount; i++) {
19769            ProcessCpuTracker.Stats st = stats.get(i);
19770            long pss = Debug.getPss(st.pid, null, memtrackTmp);
19771            if (pss > 0) {
19772                if (infoMap.indexOfKey(st.pid) < 0) {
19773                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
19774                            ProcessList.NATIVE_ADJ, -1, "native", null);
19775                    mi.pss = pss;
19776                    mi.memtrack = memtrackTmp[0];
19777                    memInfos.add(mi);
19778                }
19779            }
19780        }
19781
19782        long totalPss = 0;
19783        long totalMemtrack = 0;
19784        for (int i=0, N=memInfos.size(); i<N; i++) {
19785            ProcessMemInfo mi = memInfos.get(i);
19786            if (mi.pss == 0) {
19787                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
19788                mi.memtrack = memtrackTmp[0];
19789            }
19790            totalPss += mi.pss;
19791            totalMemtrack += mi.memtrack;
19792        }
19793        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
19794            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
19795                if (lhs.oomAdj != rhs.oomAdj) {
19796                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
19797                }
19798                if (lhs.pss != rhs.pss) {
19799                    return lhs.pss < rhs.pss ? 1 : -1;
19800                }
19801                return 0;
19802            }
19803        });
19804
19805        StringBuilder tag = new StringBuilder(128);
19806        StringBuilder stack = new StringBuilder(128);
19807        tag.append("Low on memory -- ");
19808        appendMemBucket(tag, totalPss, "total", false);
19809        appendMemBucket(stack, totalPss, "total", true);
19810
19811        StringBuilder fullNativeBuilder = new StringBuilder(1024);
19812        StringBuilder shortNativeBuilder = new StringBuilder(1024);
19813        StringBuilder fullJavaBuilder = new StringBuilder(1024);
19814
19815        boolean firstLine = true;
19816        int lastOomAdj = Integer.MIN_VALUE;
19817        long extraNativeRam = 0;
19818        long extraNativeMemtrack = 0;
19819        long cachedPss = 0;
19820        for (int i=0, N=memInfos.size(); i<N; i++) {
19821            ProcessMemInfo mi = memInfos.get(i);
19822
19823            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19824                cachedPss += mi.pss;
19825            }
19826
19827            if (mi.oomAdj != ProcessList.NATIVE_ADJ
19828                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
19829                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
19830                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
19831                if (lastOomAdj != mi.oomAdj) {
19832                    lastOomAdj = mi.oomAdj;
19833                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19834                        tag.append(" / ");
19835                    }
19836                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
19837                        if (firstLine) {
19838                            stack.append(":");
19839                            firstLine = false;
19840                        }
19841                        stack.append("\n\t at ");
19842                    } else {
19843                        stack.append("$");
19844                    }
19845                } else {
19846                    tag.append(" ");
19847                    stack.append("$");
19848                }
19849                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19850                    appendMemBucket(tag, mi.pss, mi.name, false);
19851                }
19852                appendMemBucket(stack, mi.pss, mi.name, true);
19853                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
19854                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
19855                    stack.append("(");
19856                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
19857                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
19858                            stack.append(DUMP_MEM_OOM_LABEL[k]);
19859                            stack.append(":");
19860                            stack.append(DUMP_MEM_OOM_ADJ[k]);
19861                        }
19862                    }
19863                    stack.append(")");
19864                }
19865            }
19866
19867            appendMemInfo(fullNativeBuilder, mi);
19868            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
19869                // The short form only has native processes that are >= 512K.
19870                if (mi.pss >= 512) {
19871                    appendMemInfo(shortNativeBuilder, mi);
19872                } else {
19873                    extraNativeRam += mi.pss;
19874                    extraNativeMemtrack += mi.memtrack;
19875                }
19876            } else {
19877                // Short form has all other details, but if we have collected RAM
19878                // from smaller native processes let's dump a summary of that.
19879                if (extraNativeRam > 0) {
19880                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
19881                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
19882                    shortNativeBuilder.append('\n');
19883                    extraNativeRam = 0;
19884                }
19885                appendMemInfo(fullJavaBuilder, mi);
19886            }
19887        }
19888
19889        fullJavaBuilder.append("           ");
19890        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
19891        fullJavaBuilder.append(": TOTAL");
19892        if (totalMemtrack > 0) {
19893            fullJavaBuilder.append(" (");
19894            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
19895            fullJavaBuilder.append(" memtrack)");
19896        } else {
19897        }
19898        fullJavaBuilder.append("\n");
19899
19900        MemInfoReader memInfo = new MemInfoReader();
19901        memInfo.readMemInfo();
19902        final long[] infos = memInfo.getRawInfo();
19903
19904        StringBuilder memInfoBuilder = new StringBuilder(1024);
19905        Debug.getMemInfo(infos);
19906        memInfoBuilder.append("  MemInfo: ");
19907        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
19908        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
19909        memInfoBuilder.append(stringifyKBSize(
19910                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
19911        memInfoBuilder.append(stringifyKBSize(
19912                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
19913        memInfoBuilder.append(stringifyKBSize(
19914                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
19915        memInfoBuilder.append("           ");
19916        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
19917        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
19918        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
19919        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
19920        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
19921            memInfoBuilder.append("  ZRAM: ");
19922            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
19923            memInfoBuilder.append(" RAM, ");
19924            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
19925            memInfoBuilder.append(" swap total, ");
19926            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
19927            memInfoBuilder.append(" swap free\n");
19928        }
19929        final long[] ksm = getKsmInfo();
19930        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
19931                || ksm[KSM_VOLATILE] != 0) {
19932            memInfoBuilder.append("  KSM: ");
19933            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
19934            memInfoBuilder.append(" saved from shared ");
19935            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
19936            memInfoBuilder.append("\n       ");
19937            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
19938            memInfoBuilder.append(" unshared; ");
19939            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
19940            memInfoBuilder.append(" volatile\n");
19941        }
19942        memInfoBuilder.append("  Free RAM: ");
19943        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19944                + memInfo.getFreeSizeKb()));
19945        memInfoBuilder.append("\n");
19946        memInfoBuilder.append("  Used RAM: ");
19947        memInfoBuilder.append(stringifyKBSize(
19948                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
19949        memInfoBuilder.append("\n");
19950        memInfoBuilder.append("  Lost RAM: ");
19951        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
19952                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19953                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
19954        memInfoBuilder.append("\n");
19955        Slog.i(TAG, "Low on memory:");
19956        Slog.i(TAG, shortNativeBuilder.toString());
19957        Slog.i(TAG, fullJavaBuilder.toString());
19958        Slog.i(TAG, memInfoBuilder.toString());
19959
19960        StringBuilder dropBuilder = new StringBuilder(1024);
19961        /*
19962        StringWriter oomSw = new StringWriter();
19963        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
19964        StringWriter catSw = new StringWriter();
19965        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19966        String[] emptyArgs = new String[] { };
19967        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
19968        oomPw.flush();
19969        String oomString = oomSw.toString();
19970        */
19971        dropBuilder.append("Low on memory:");
19972        dropBuilder.append(stack);
19973        dropBuilder.append('\n');
19974        dropBuilder.append(fullNativeBuilder);
19975        dropBuilder.append(fullJavaBuilder);
19976        dropBuilder.append('\n');
19977        dropBuilder.append(memInfoBuilder);
19978        dropBuilder.append('\n');
19979        /*
19980        dropBuilder.append(oomString);
19981        dropBuilder.append('\n');
19982        */
19983        StringWriter catSw = new StringWriter();
19984        synchronized (ActivityManagerService.this) {
19985            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19986            String[] emptyArgs = new String[] { };
19987            catPw.println();
19988            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
19989            catPw.println();
19990            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
19991                    false, null).dumpLocked();
19992            catPw.println();
19993            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
19994            catPw.flush();
19995        }
19996        dropBuilder.append(catSw.toString());
19997        StatsLog.write(StatsLog.LOW_MEM_REPORTED);
19998        addErrorToDropBox("lowmem", null, "system_server", null,
19999                null, tag.toString(), dropBuilder.toString(), null, null);
20000        //Slog.i(TAG, "Sent to dropbox:");
20001        //Slog.i(TAG, dropBuilder.toString());
20002        synchronized (ActivityManagerService.this) {
20003            long now = SystemClock.uptimeMillis();
20004            if (mLastMemUsageReportTime < now) {
20005                mLastMemUsageReportTime = now;
20006            }
20007        }
20008    }
20009
20010    /**
20011     * Searches array of arguments for the specified string
20012     * @param args array of argument strings
20013     * @param value value to search for
20014     * @return true if the value is contained in the array
20015     */
20016    private static boolean scanArgs(String[] args, String value) {
20017        if (args != null) {
20018            for (String arg : args) {
20019                if (value.equals(arg)) {
20020                    return true;
20021                }
20022            }
20023        }
20024        return false;
20025    }
20026
20027    private final boolean removeDyingProviderLocked(ProcessRecord proc,
20028            ContentProviderRecord cpr, boolean always) {
20029        final boolean inLaunching = mLaunchingProviders.contains(cpr);
20030
20031        if (!inLaunching || always) {
20032            synchronized (cpr) {
20033                cpr.launchingApp = null;
20034                cpr.notifyAll();
20035            }
20036            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
20037            String names[] = cpr.info.authority.split(";");
20038            for (int j = 0; j < names.length; j++) {
20039                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
20040            }
20041        }
20042
20043        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
20044            ContentProviderConnection conn = cpr.connections.get(i);
20045            if (conn.waiting) {
20046                // If this connection is waiting for the provider, then we don't
20047                // need to mess with its process unless we are always removing
20048                // or for some reason the provider is not currently launching.
20049                if (inLaunching && !always) {
20050                    continue;
20051                }
20052            }
20053            ProcessRecord capp = conn.client;
20054            conn.dead = true;
20055            if (conn.stableCount > 0) {
20056                if (!capp.persistent && capp.thread != null
20057                        && capp.pid != 0
20058                        && capp.pid != MY_PID) {
20059                    capp.kill("depends on provider "
20060                            + cpr.name.flattenToShortString()
20061                            + " in dying proc " + (proc != null ? proc.processName : "??")
20062                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
20063                }
20064            } else if (capp.thread != null && conn.provider.provider != null) {
20065                try {
20066                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
20067                } catch (RemoteException e) {
20068                }
20069                // In the protocol here, we don't expect the client to correctly
20070                // clean up this connection, we'll just remove it.
20071                cpr.connections.remove(i);
20072                if (conn.client.conProviders.remove(conn)) {
20073                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
20074                }
20075            }
20076        }
20077
20078        if (inLaunching && always) {
20079            mLaunchingProviders.remove(cpr);
20080        }
20081        return inLaunching;
20082    }
20083
20084    /**
20085     * Main code for cleaning up a process when it has gone away.  This is
20086     * called both as a result of the process dying, or directly when stopping
20087     * a process when running in single process mode.
20088     *
20089     * @return Returns true if the given process has been restarted, so the
20090     * app that was passed in must remain on the process lists.
20091     */
20092    @GuardedBy("this")
20093    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
20094            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
20095        if (index >= 0) {
20096            removeLruProcessLocked(app);
20097            ProcessList.remove(app.pid);
20098        }
20099
20100        mProcessesToGc.remove(app);
20101        mPendingPssProcesses.remove(app);
20102        ProcessList.abortNextPssTime(app.procStateMemTracker);
20103
20104        // Dismiss any open dialogs.
20105        if (app.crashDialog != null && !app.forceCrashReport) {
20106            app.crashDialog.dismiss();
20107            app.crashDialog = null;
20108        }
20109        if (app.anrDialog != null) {
20110            app.anrDialog.dismiss();
20111            app.anrDialog = null;
20112        }
20113        if (app.waitDialog != null) {
20114            app.waitDialog.dismiss();
20115            app.waitDialog = null;
20116        }
20117
20118        app.crashing = false;
20119        app.notResponding = false;
20120
20121        app.resetPackageList(mProcessStats);
20122        app.unlinkDeathRecipient();
20123        app.makeInactive(mProcessStats);
20124        app.waitingToKill = null;
20125        app.forcingToImportant = null;
20126        updateProcessForegroundLocked(app, false, false);
20127        app.foregroundActivities = false;
20128        app.hasShownUi = false;
20129        app.treatLikeActivity = false;
20130        app.hasAboveClient = false;
20131        app.hasClientActivities = false;
20132
20133        mServices.killServicesLocked(app, allowRestart);
20134
20135        boolean restart = false;
20136
20137        // Remove published content providers.
20138        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
20139            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
20140            final boolean always = app.bad || !allowRestart;
20141            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
20142            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
20143                // We left the provider in the launching list, need to
20144                // restart it.
20145                restart = true;
20146            }
20147
20148            cpr.provider = null;
20149            cpr.proc = null;
20150        }
20151        app.pubProviders.clear();
20152
20153        // Take care of any launching providers waiting for this process.
20154        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
20155            restart = true;
20156        }
20157
20158        // Unregister from connected content providers.
20159        if (!app.conProviders.isEmpty()) {
20160            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
20161                ContentProviderConnection conn = app.conProviders.get(i);
20162                conn.provider.connections.remove(conn);
20163                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
20164                        conn.provider.name);
20165            }
20166            app.conProviders.clear();
20167        }
20168
20169        // At this point there may be remaining entries in mLaunchingProviders
20170        // where we were the only one waiting, so they are no longer of use.
20171        // Look for these and clean up if found.
20172        // XXX Commented out for now.  Trying to figure out a way to reproduce
20173        // the actual situation to identify what is actually going on.
20174        if (false) {
20175            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20176                ContentProviderRecord cpr = mLaunchingProviders.get(i);
20177                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
20178                    synchronized (cpr) {
20179                        cpr.launchingApp = null;
20180                        cpr.notifyAll();
20181                    }
20182                }
20183            }
20184        }
20185
20186        skipCurrentReceiverLocked(app);
20187
20188        // Unregister any receivers.
20189        for (int i = app.receivers.size() - 1; i >= 0; i--) {
20190            removeReceiverLocked(app.receivers.valueAt(i));
20191        }
20192        app.receivers.clear();
20193
20194        // If the app is undergoing backup, tell the backup manager about it
20195        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
20196            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
20197                    + mBackupTarget.appInfo + " died during backup");
20198            mHandler.post(new Runnable() {
20199                @Override
20200                public void run(){
20201                    try {
20202                        IBackupManager bm = IBackupManager.Stub.asInterface(
20203                                ServiceManager.getService(Context.BACKUP_SERVICE));
20204                        bm.agentDisconnected(app.info.packageName);
20205                    } catch (RemoteException e) {
20206                        // can't happen; backup manager is local
20207                    }
20208                }
20209            });
20210        }
20211
20212        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
20213            ProcessChangeItem item = mPendingProcessChanges.get(i);
20214            if (app.pid > 0 && item.pid == app.pid) {
20215                mPendingProcessChanges.remove(i);
20216                mAvailProcessChanges.add(item);
20217            }
20218        }
20219        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
20220                null).sendToTarget();
20221
20222        // If the caller is restarting this app, then leave it in its
20223        // current lists and let the caller take care of it.
20224        if (restarting) {
20225            return false;
20226        }
20227
20228        if (!app.persistent || app.isolated) {
20229            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
20230                    "Removing non-persistent process during cleanup: " + app);
20231            if (!replacingPid) {
20232                removeProcessNameLocked(app.processName, app.uid, app);
20233            }
20234            if (mHeavyWeightProcess == app) {
20235                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
20236                        mHeavyWeightProcess.userId, 0));
20237                mHeavyWeightProcess = null;
20238            }
20239        } else if (!app.removed) {
20240            // This app is persistent, so we need to keep its record around.
20241            // If it is not already on the pending app list, add it there
20242            // and start a new process for it.
20243            if (mPersistentStartingProcesses.indexOf(app) < 0) {
20244                mPersistentStartingProcesses.add(app);
20245                restart = true;
20246            }
20247        }
20248        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
20249                TAG_CLEANUP, "Clean-up removing on hold: " + app);
20250        mProcessesOnHold.remove(app);
20251
20252        if (app == mHomeProcess) {
20253            mHomeProcess = null;
20254        }
20255        if (app == mPreviousProcess) {
20256            mPreviousProcess = null;
20257        }
20258
20259        if (restart && !app.isolated) {
20260            // We have components that still need to be running in the
20261            // process, so re-launch it.
20262            if (index < 0) {
20263                ProcessList.remove(app.pid);
20264            }
20265            addProcessNameLocked(app);
20266            app.pendingStart = false;
20267            startProcessLocked(app, "restart", app.processName);
20268            return true;
20269        } else if (app.pid > 0 && app.pid != MY_PID) {
20270            // Goodbye!
20271            boolean removed;
20272            synchronized (mPidsSelfLocked) {
20273                mPidsSelfLocked.remove(app.pid);
20274                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
20275            }
20276            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
20277            if (app.isolated) {
20278                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
20279            }
20280            app.setPid(0);
20281        }
20282        return false;
20283    }
20284
20285    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
20286        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20287            ContentProviderRecord cpr = mLaunchingProviders.get(i);
20288            if (cpr.launchingApp == app) {
20289                return true;
20290            }
20291        }
20292        return false;
20293    }
20294
20295    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
20296        // Look through the content providers we are waiting to have launched,
20297        // and if any run in this process then either schedule a restart of
20298        // the process or kill the client waiting for it if this process has
20299        // gone bad.
20300        boolean restart = false;
20301        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
20302            ContentProviderRecord cpr = mLaunchingProviders.get(i);
20303            if (cpr.launchingApp == app) {
20304                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
20305                    restart = true;
20306                } else {
20307                    removeDyingProviderLocked(app, cpr, true);
20308                }
20309            }
20310        }
20311        return restart;
20312    }
20313
20314    // =========================================================
20315    // SERVICES
20316    // =========================================================
20317
20318    @Override
20319    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
20320        enforceNotIsolatedCaller("getServices");
20321
20322        final int callingUid = Binder.getCallingUid();
20323        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
20324            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
20325        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
20326            callingUid);
20327        synchronized (this) {
20328            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
20329                allowed, canInteractAcrossUsers);
20330        }
20331    }
20332
20333    @Override
20334    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
20335        enforceNotIsolatedCaller("getRunningServiceControlPanel");
20336        synchronized (this) {
20337            return mServices.getRunningServiceControlPanelLocked(name);
20338        }
20339    }
20340
20341    @Override
20342    public ComponentName startService(IApplicationThread caller, Intent service,
20343            String resolvedType, boolean requireForeground, String callingPackage, int userId)
20344            throws TransactionTooLargeException {
20345        enforceNotIsolatedCaller("startService");
20346        // Refuse possible leaked file descriptors
20347        if (service != null && service.hasFileDescriptors() == true) {
20348            throw new IllegalArgumentException("File descriptors passed in Intent");
20349        }
20350
20351        if (callingPackage == null) {
20352            throw new IllegalArgumentException("callingPackage cannot be null");
20353        }
20354
20355        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20356                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
20357        synchronized(this) {
20358            final int callingPid = Binder.getCallingPid();
20359            final int callingUid = Binder.getCallingUid();
20360            final long origId = Binder.clearCallingIdentity();
20361            ComponentName res;
20362            try {
20363                res = mServices.startServiceLocked(caller, service,
20364                        resolvedType, callingPid, callingUid,
20365                        requireForeground, callingPackage, userId);
20366            } finally {
20367                Binder.restoreCallingIdentity(origId);
20368            }
20369            return res;
20370        }
20371    }
20372
20373    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
20374            boolean fgRequired, String callingPackage, int userId)
20375            throws TransactionTooLargeException {
20376        synchronized(this) {
20377            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20378                    "startServiceInPackage: " + service + " type=" + resolvedType);
20379            final long origId = Binder.clearCallingIdentity();
20380            ComponentName res;
20381            try {
20382                res = mServices.startServiceLocked(null, service,
20383                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
20384            } finally {
20385                Binder.restoreCallingIdentity(origId);
20386            }
20387            return res;
20388        }
20389    }
20390
20391    @Override
20392    public int stopService(IApplicationThread caller, Intent service,
20393            String resolvedType, int userId) {
20394        enforceNotIsolatedCaller("stopService");
20395        // Refuse possible leaked file descriptors
20396        if (service != null && service.hasFileDescriptors() == true) {
20397            throw new IllegalArgumentException("File descriptors passed in Intent");
20398        }
20399
20400        synchronized(this) {
20401            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
20402        }
20403    }
20404
20405    @Override
20406    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
20407        enforceNotIsolatedCaller("peekService");
20408        // Refuse possible leaked file descriptors
20409        if (service != null && service.hasFileDescriptors() == true) {
20410            throw new IllegalArgumentException("File descriptors passed in Intent");
20411        }
20412
20413        if (callingPackage == null) {
20414            throw new IllegalArgumentException("callingPackage cannot be null");
20415        }
20416
20417        synchronized(this) {
20418            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
20419        }
20420    }
20421
20422    @Override
20423    public boolean stopServiceToken(ComponentName className, IBinder token,
20424            int startId) {
20425        synchronized(this) {
20426            return mServices.stopServiceTokenLocked(className, token, startId);
20427        }
20428    }
20429
20430    @Override
20431    public void setServiceForeground(ComponentName className, IBinder token,
20432            int id, Notification notification, int flags) {
20433        synchronized(this) {
20434            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
20435        }
20436    }
20437
20438    @Override
20439    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
20440            boolean requireFull, String name, String callerPackage) {
20441        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
20442                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
20443    }
20444
20445    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
20446            String className, int flags) {
20447        boolean result = false;
20448        // For apps that don't have pre-defined UIDs, check for permission
20449        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
20450            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20451                if (ActivityManager.checkUidPermission(
20452                        INTERACT_ACROSS_USERS,
20453                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
20454                    ComponentName comp = new ComponentName(aInfo.packageName, className);
20455                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
20456                            + " requests FLAG_SINGLE_USER, but app does not hold "
20457                            + INTERACT_ACROSS_USERS;
20458                    Slog.w(TAG, msg);
20459                    throw new SecurityException(msg);
20460                }
20461                // Permission passed
20462                result = true;
20463            }
20464        } else if ("system".equals(componentProcessName)) {
20465            result = true;
20466        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20467            // Phone app and persistent apps are allowed to export singleuser providers.
20468            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
20469                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
20470        }
20471        if (DEBUG_MU) Slog.v(TAG_MU,
20472                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
20473                + Integer.toHexString(flags) + ") = " + result);
20474        return result;
20475    }
20476
20477    /**
20478     * Checks to see if the caller is in the same app as the singleton
20479     * component, or the component is in a special app. It allows special apps
20480     * to export singleton components but prevents exporting singleton
20481     * components for regular apps.
20482     */
20483    boolean isValidSingletonCall(int callingUid, int componentUid) {
20484        int componentAppId = UserHandle.getAppId(componentUid);
20485        return UserHandle.isSameApp(callingUid, componentUid)
20486                || componentAppId == SYSTEM_UID
20487                || componentAppId == PHONE_UID
20488                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
20489                        == PackageManager.PERMISSION_GRANTED;
20490    }
20491
20492    public int bindService(IApplicationThread caller, IBinder token, Intent service,
20493            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
20494            int userId) throws TransactionTooLargeException {
20495        enforceNotIsolatedCaller("bindService");
20496
20497        // Refuse possible leaked file descriptors
20498        if (service != null && service.hasFileDescriptors() == true) {
20499            throw new IllegalArgumentException("File descriptors passed in Intent");
20500        }
20501
20502        if (callingPackage == null) {
20503            throw new IllegalArgumentException("callingPackage cannot be null");
20504        }
20505
20506        synchronized(this) {
20507            return mServices.bindServiceLocked(caller, token, service,
20508                    resolvedType, connection, flags, callingPackage, userId);
20509        }
20510    }
20511
20512    public boolean unbindService(IServiceConnection connection) {
20513        synchronized (this) {
20514            return mServices.unbindServiceLocked(connection);
20515        }
20516    }
20517
20518    public void publishService(IBinder token, Intent intent, IBinder service) {
20519        // Refuse possible leaked file descriptors
20520        if (intent != null && intent.hasFileDescriptors() == true) {
20521            throw new IllegalArgumentException("File descriptors passed in Intent");
20522        }
20523
20524        synchronized(this) {
20525            if (!(token instanceof ServiceRecord)) {
20526                throw new IllegalArgumentException("Invalid service token");
20527            }
20528            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
20529        }
20530    }
20531
20532    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
20533        // Refuse possible leaked file descriptors
20534        if (intent != null && intent.hasFileDescriptors() == true) {
20535            throw new IllegalArgumentException("File descriptors passed in Intent");
20536        }
20537
20538        synchronized(this) {
20539            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
20540        }
20541    }
20542
20543    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
20544        synchronized(this) {
20545            if (!(token instanceof ServiceRecord)) {
20546                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
20547                throw new IllegalArgumentException("Invalid service token");
20548            }
20549            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
20550        }
20551    }
20552
20553    // =========================================================
20554    // BACKUP AND RESTORE
20555    // =========================================================
20556
20557    // Cause the target app to be launched if necessary and its backup agent
20558    // instantiated.  The backup agent will invoke backupAgentCreated() on the
20559    // activity manager to announce its creation.
20560    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
20561        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
20562        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
20563
20564        IPackageManager pm = AppGlobals.getPackageManager();
20565        ApplicationInfo app = null;
20566        try {
20567            app = pm.getApplicationInfo(packageName, STOCK_PM_FLAGS, userId);
20568        } catch (RemoteException e) {
20569            // can't happen; package manager is process-local
20570        }
20571        if (app == null) {
20572            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
20573            return false;
20574        }
20575
20576        int oldBackupUid;
20577        int newBackupUid;
20578
20579        synchronized(this) {
20580            // !!! TODO: currently no check here that we're already bound
20581            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
20582            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20583            synchronized (stats) {
20584                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
20585            }
20586
20587            // Backup agent is now in use, its package can't be stopped.
20588            try {
20589                AppGlobals.getPackageManager().setPackageStoppedState(
20590                        app.packageName, false, UserHandle.getUserId(app.uid));
20591            } catch (RemoteException e) {
20592            } catch (IllegalArgumentException e) {
20593                Slog.w(TAG, "Failed trying to unstop package "
20594                        + app.packageName + ": " + e);
20595            }
20596
20597            BackupRecord r = new BackupRecord(ss, app, backupMode);
20598            ComponentName hostingName =
20599                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
20600                            ? new ComponentName(app.packageName, app.backupAgentName)
20601                            : new ComponentName("android", "FullBackupAgent");
20602            // startProcessLocked() returns existing proc's record if it's already running
20603            ProcessRecord proc = startProcessLocked(app.processName, app,
20604                    false, 0, "backup", hostingName, false, false, false);
20605            if (proc == null) {
20606                Slog.e(TAG, "Unable to start backup agent process " + r);
20607                return false;
20608            }
20609
20610            // If the app is a regular app (uid >= 10000) and not the system server or phone
20611            // process, etc, then mark it as being in full backup so that certain calls to the
20612            // process can be blocked. This is not reset to false anywhere because we kill the
20613            // process after the full backup is done and the ProcessRecord will vaporize anyway.
20614            if (UserHandle.isApp(app.uid) &&
20615                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
20616                proc.inFullBackup = true;
20617            }
20618            r.app = proc;
20619            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20620            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
20621            mBackupTarget = r;
20622            mBackupAppName = app.packageName;
20623
20624            // Try not to kill the process during backup
20625            updateOomAdjLocked(proc, true);
20626
20627            // If the process is already attached, schedule the creation of the backup agent now.
20628            // If it is not yet live, this will be done when it attaches to the framework.
20629            if (proc.thread != null) {
20630                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
20631                try {
20632                    proc.thread.scheduleCreateBackupAgent(app,
20633                            compatibilityInfoForPackageLocked(app), backupMode);
20634                } catch (RemoteException e) {
20635                    // Will time out on the backup manager side
20636                }
20637            } else {
20638                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
20639            }
20640            // Invariants: at this point, the target app process exists and the application
20641            // is either already running or in the process of coming up.  mBackupTarget and
20642            // mBackupAppName describe the app, so that when it binds back to the AM we
20643            // know that it's scheduled for a backup-agent operation.
20644        }
20645
20646        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20647        if (oldBackupUid != -1) {
20648            js.removeBackingUpUid(oldBackupUid);
20649        }
20650        if (newBackupUid != -1) {
20651            js.addBackingUpUid(newBackupUid);
20652        }
20653
20654        return true;
20655    }
20656
20657    @Override
20658    public void clearPendingBackup() {
20659        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
20660        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
20661
20662        synchronized (this) {
20663            mBackupTarget = null;
20664            mBackupAppName = null;
20665        }
20666
20667        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20668        js.clearAllBackingUpUids();
20669    }
20670
20671    // A backup agent has just come up
20672    public void backupAgentCreated(String agentPackageName, IBinder agent) {
20673        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
20674                + " = " + agent);
20675
20676        synchronized(this) {
20677            if (!agentPackageName.equals(mBackupAppName)) {
20678                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
20679                return;
20680            }
20681        }
20682
20683        long oldIdent = Binder.clearCallingIdentity();
20684        try {
20685            IBackupManager bm = IBackupManager.Stub.asInterface(
20686                    ServiceManager.getService(Context.BACKUP_SERVICE));
20687            bm.agentConnected(agentPackageName, agent);
20688        } catch (RemoteException e) {
20689            // can't happen; the backup manager service is local
20690        } catch (Exception e) {
20691            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
20692            e.printStackTrace();
20693        } finally {
20694            Binder.restoreCallingIdentity(oldIdent);
20695        }
20696    }
20697
20698    // done with this agent
20699    public void unbindBackupAgent(ApplicationInfo appInfo) {
20700        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
20701        if (appInfo == null) {
20702            Slog.w(TAG, "unbind backup agent for null app");
20703            return;
20704        }
20705
20706        int oldBackupUid;
20707
20708        synchronized(this) {
20709            try {
20710                if (mBackupAppName == null) {
20711                    Slog.w(TAG, "Unbinding backup agent with no active backup");
20712                    return;
20713                }
20714
20715                if (!mBackupAppName.equals(appInfo.packageName)) {
20716                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
20717                    return;
20718                }
20719
20720                // Not backing this app up any more; reset its OOM adjustment
20721                final ProcessRecord proc = mBackupTarget.app;
20722                updateOomAdjLocked(proc, true);
20723                proc.inFullBackup = false;
20724
20725                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20726
20727                // If the app crashed during backup, 'thread' will be null here
20728                if (proc.thread != null) {
20729                    try {
20730                        proc.thread.scheduleDestroyBackupAgent(appInfo,
20731                                compatibilityInfoForPackageLocked(appInfo));
20732                    } catch (Exception e) {
20733                        Slog.e(TAG, "Exception when unbinding backup agent:");
20734                        e.printStackTrace();
20735                    }
20736                }
20737            } finally {
20738                mBackupTarget = null;
20739                mBackupAppName = null;
20740            }
20741        }
20742
20743        if (oldBackupUid != -1) {
20744            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20745            js.removeBackingUpUid(oldBackupUid);
20746        }
20747    }
20748
20749    // =========================================================
20750    // BROADCASTS
20751    // =========================================================
20752
20753    private boolean isInstantApp(ProcessRecord record, @Nullable String callerPackage, int uid) {
20754        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
20755            return false;
20756        }
20757        // Easy case -- we have the app's ProcessRecord.
20758        if (record != null) {
20759            return record.info.isInstantApp();
20760        }
20761        // Otherwise check with PackageManager.
20762        IPackageManager pm = AppGlobals.getPackageManager();
20763        try {
20764            if (callerPackage == null) {
20765                final String[] packageNames = pm.getPackagesForUid(uid);
20766                if (packageNames == null || packageNames.length == 0) {
20767                    throw new IllegalArgumentException("Unable to determine caller package name");
20768                }
20769                // Instant Apps can't use shared uids, so its safe to only check the first package.
20770                callerPackage = packageNames[0];
20771            }
20772            mAppOpsService.checkPackage(uid, callerPackage);
20773            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
20774        } catch (RemoteException e) {
20775            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
20776            return true;
20777        }
20778    }
20779
20780    boolean isPendingBroadcastProcessLocked(int pid) {
20781        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
20782                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
20783    }
20784
20785    void skipPendingBroadcastLocked(int pid) {
20786            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
20787            for (BroadcastQueue queue : mBroadcastQueues) {
20788                queue.skipPendingBroadcastLocked(pid);
20789            }
20790    }
20791
20792    // The app just attached; send any pending broadcasts that it should receive
20793    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
20794        boolean didSomething = false;
20795        for (BroadcastQueue queue : mBroadcastQueues) {
20796            didSomething |= queue.sendPendingBroadcastsLocked(app);
20797        }
20798        return didSomething;
20799    }
20800
20801    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
20802            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
20803            int flags) {
20804        enforceNotIsolatedCaller("registerReceiver");
20805        ArrayList<Intent> stickyIntents = null;
20806        ProcessRecord callerApp = null;
20807        final boolean visibleToInstantApps
20808                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
20809        int callingUid;
20810        int callingPid;
20811        boolean instantApp;
20812        synchronized(this) {
20813            if (caller != null) {
20814                callerApp = getRecordForAppLocked(caller);
20815                if (callerApp == null) {
20816                    throw new SecurityException(
20817                            "Unable to find app for caller " + caller
20818                            + " (pid=" + Binder.getCallingPid()
20819                            + ") when registering receiver " + receiver);
20820                }
20821                if (callerApp.info.uid != SYSTEM_UID &&
20822                        !callerApp.pkgList.containsKey(callerPackage) &&
20823                        !"android".equals(callerPackage)) {
20824                    throw new SecurityException("Given caller package " + callerPackage
20825                            + " is not running in process " + callerApp);
20826                }
20827                callingUid = callerApp.info.uid;
20828                callingPid = callerApp.pid;
20829            } else {
20830                callerPackage = null;
20831                callingUid = Binder.getCallingUid();
20832                callingPid = Binder.getCallingPid();
20833            }
20834
20835            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
20836            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20837                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
20838
20839            Iterator<String> actions = filter.actionsIterator();
20840            if (actions == null) {
20841                ArrayList<String> noAction = new ArrayList<String>(1);
20842                noAction.add(null);
20843                actions = noAction.iterator();
20844            }
20845
20846            // Collect stickies of users
20847            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
20848            while (actions.hasNext()) {
20849                String action = actions.next();
20850                for (int id : userIds) {
20851                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
20852                    if (stickies != null) {
20853                        ArrayList<Intent> intents = stickies.get(action);
20854                        if (intents != null) {
20855                            if (stickyIntents == null) {
20856                                stickyIntents = new ArrayList<Intent>();
20857                            }
20858                            stickyIntents.addAll(intents);
20859                        }
20860                    }
20861                }
20862            }
20863        }
20864
20865        ArrayList<Intent> allSticky = null;
20866        if (stickyIntents != null) {
20867            final ContentResolver resolver = mContext.getContentResolver();
20868            // Look for any matching sticky broadcasts...
20869            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
20870                Intent intent = stickyIntents.get(i);
20871                // Don't provided intents that aren't available to instant apps.
20872                if (instantApp &&
20873                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
20874                    continue;
20875                }
20876                // If intent has scheme "content", it will need to acccess
20877                // provider that needs to lock mProviderMap in ActivityThread
20878                // and also it may need to wait application response, so we
20879                // cannot lock ActivityManagerService here.
20880                if (filter.match(resolver, intent, true, TAG) >= 0) {
20881                    if (allSticky == null) {
20882                        allSticky = new ArrayList<Intent>();
20883                    }
20884                    allSticky.add(intent);
20885                }
20886            }
20887        }
20888
20889        // The first sticky in the list is returned directly back to the client.
20890        Intent sticky = allSticky != null ? allSticky.get(0) : null;
20891        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
20892        if (receiver == null) {
20893            return sticky;
20894        }
20895
20896        synchronized (this) {
20897            if (callerApp != null && (callerApp.thread == null
20898                    || callerApp.thread.asBinder() != caller.asBinder())) {
20899                // Original caller already died
20900                return null;
20901            }
20902            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20903            if (rl == null) {
20904                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
20905                        userId, receiver);
20906                if (rl.app != null) {
20907                    final int totalReceiversForApp = rl.app.receivers.size();
20908                    if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
20909                        throw new IllegalStateException("Too many receivers, total of "
20910                                + totalReceiversForApp + ", registered for pid: "
20911                                + rl.pid + ", callerPackage: " + callerPackage);
20912                    }
20913                    rl.app.receivers.add(rl);
20914                } else {
20915                    try {
20916                        receiver.asBinder().linkToDeath(rl, 0);
20917                    } catch (RemoteException e) {
20918                        return sticky;
20919                    }
20920                    rl.linkedToDeath = true;
20921                }
20922                mRegisteredReceivers.put(receiver.asBinder(), rl);
20923            } else if (rl.uid != callingUid) {
20924                throw new IllegalArgumentException(
20925                        "Receiver requested to register for uid " + callingUid
20926                        + " was previously registered for uid " + rl.uid
20927                        + " callerPackage is " + callerPackage);
20928            } else if (rl.pid != callingPid) {
20929                throw new IllegalArgumentException(
20930                        "Receiver requested to register for pid " + callingPid
20931                        + " was previously registered for pid " + rl.pid
20932                        + " callerPackage is " + callerPackage);
20933            } else if (rl.userId != userId) {
20934                throw new IllegalArgumentException(
20935                        "Receiver requested to register for user " + userId
20936                        + " was previously registered for user " + rl.userId
20937                        + " callerPackage is " + callerPackage);
20938            }
20939            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
20940                    permission, callingUid, userId, instantApp, visibleToInstantApps);
20941            if (rl.containsFilter(filter)) {
20942                Slog.w(TAG, "Receiver with filter " + filter
20943                        + " already registered for pid " + rl.pid
20944                        + ", callerPackage is " + callerPackage);
20945            } else {
20946                rl.add(bf);
20947                if (!bf.debugCheck()) {
20948                    Slog.w(TAG, "==> For Dynamic broadcast");
20949                }
20950                mReceiverResolver.addFilter(bf);
20951            }
20952
20953            // Enqueue broadcasts for all existing stickies that match
20954            // this filter.
20955            if (allSticky != null) {
20956                ArrayList receivers = new ArrayList();
20957                receivers.add(bf);
20958
20959                final int stickyCount = allSticky.size();
20960                for (int i = 0; i < stickyCount; i++) {
20961                    Intent intent = allSticky.get(i);
20962                    BroadcastQueue queue = broadcastQueueForIntent(intent);
20963                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
20964                            null, -1, -1, false, null, null, OP_NONE, null, receivers,
20965                            null, 0, null, null, false, true, true, -1);
20966                    queue.enqueueParallelBroadcastLocked(r);
20967                    queue.scheduleBroadcastsLocked();
20968                }
20969            }
20970
20971            return sticky;
20972        }
20973    }
20974
20975    public void unregisterReceiver(IIntentReceiver receiver) {
20976        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
20977
20978        final long origId = Binder.clearCallingIdentity();
20979        try {
20980            boolean doTrim = false;
20981
20982            synchronized(this) {
20983                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20984                if (rl != null) {
20985                    final BroadcastRecord r = rl.curBroadcast;
20986                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
20987                        final boolean doNext = r.queue.finishReceiverLocked(
20988                                r, r.resultCode, r.resultData, r.resultExtras,
20989                                r.resultAbort, false);
20990                        if (doNext) {
20991                            doTrim = true;
20992                            r.queue.processNextBroadcast(false);
20993                        }
20994                    }
20995
20996                    if (rl.app != null) {
20997                        rl.app.receivers.remove(rl);
20998                    }
20999                    removeReceiverLocked(rl);
21000                    if (rl.linkedToDeath) {
21001                        rl.linkedToDeath = false;
21002                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
21003                    }
21004                }
21005            }
21006
21007            // If we actually concluded any broadcasts, we might now be able
21008            // to trim the recipients' apps from our working set
21009            if (doTrim) {
21010                trimApplications();
21011                return;
21012            }
21013
21014        } finally {
21015            Binder.restoreCallingIdentity(origId);
21016        }
21017    }
21018
21019    void removeReceiverLocked(ReceiverList rl) {
21020        mRegisteredReceivers.remove(rl.receiver.asBinder());
21021        for (int i = rl.size() - 1; i >= 0; i--) {
21022            mReceiverResolver.removeFilter(rl.get(i));
21023        }
21024    }
21025
21026    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
21027        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21028            ProcessRecord r = mLruProcesses.get(i);
21029            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
21030                try {
21031                    r.thread.dispatchPackageBroadcast(cmd, packages);
21032                } catch (RemoteException ex) {
21033                }
21034            }
21035        }
21036    }
21037
21038    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
21039            int callingUid, int[] users) {
21040        // TODO: come back and remove this assumption to triage all broadcasts
21041        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
21042
21043        List<ResolveInfo> receivers = null;
21044        try {
21045            HashSet<ComponentName> singleUserReceivers = null;
21046            boolean scannedFirstReceivers = false;
21047            for (int user : users) {
21048                // Skip users that have Shell restrictions, with exception of always permitted
21049                // Shell broadcasts
21050                if (callingUid == SHELL_UID
21051                        && mUserController.hasUserRestriction(
21052                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
21053                        && !isPermittedShellBroadcast(intent)) {
21054                    continue;
21055                }
21056                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
21057                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
21058                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
21059                    // If this is not the system user, we need to check for
21060                    // any receivers that should be filtered out.
21061                    for (int i=0; i<newReceivers.size(); i++) {
21062                        ResolveInfo ri = newReceivers.get(i);
21063                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
21064                            newReceivers.remove(i);
21065                            i--;
21066                        }
21067                    }
21068                }
21069                if (newReceivers != null && newReceivers.size() == 0) {
21070                    newReceivers = null;
21071                }
21072                if (receivers == null) {
21073                    receivers = newReceivers;
21074                } else if (newReceivers != null) {
21075                    // We need to concatenate the additional receivers
21076                    // found with what we have do far.  This would be easy,
21077                    // but we also need to de-dup any receivers that are
21078                    // singleUser.
21079                    if (!scannedFirstReceivers) {
21080                        // Collect any single user receivers we had already retrieved.
21081                        scannedFirstReceivers = true;
21082                        for (int i=0; i<receivers.size(); i++) {
21083                            ResolveInfo ri = receivers.get(i);
21084                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
21085                                ComponentName cn = new ComponentName(
21086                                        ri.activityInfo.packageName, ri.activityInfo.name);
21087                                if (singleUserReceivers == null) {
21088                                    singleUserReceivers = new HashSet<ComponentName>();
21089                                }
21090                                singleUserReceivers.add(cn);
21091                            }
21092                        }
21093                    }
21094                    // Add the new results to the existing results, tracking
21095                    // and de-dupping single user receivers.
21096                    for (int i=0; i<newReceivers.size(); i++) {
21097                        ResolveInfo ri = newReceivers.get(i);
21098                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
21099                            ComponentName cn = new ComponentName(
21100                                    ri.activityInfo.packageName, ri.activityInfo.name);
21101                            if (singleUserReceivers == null) {
21102                                singleUserReceivers = new HashSet<ComponentName>();
21103                            }
21104                            if (!singleUserReceivers.contains(cn)) {
21105                                singleUserReceivers.add(cn);
21106                                receivers.add(ri);
21107                            }
21108                        } else {
21109                            receivers.add(ri);
21110                        }
21111                    }
21112                }
21113            }
21114        } catch (RemoteException ex) {
21115            // pm is in same process, this will never happen.
21116        }
21117        return receivers;
21118    }
21119
21120    private boolean isPermittedShellBroadcast(Intent intent) {
21121        // remote bugreport should always be allowed to be taken
21122        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
21123    }
21124
21125    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
21126            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
21127        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21128            // Don't yell about broadcasts sent via shell
21129            return;
21130        }
21131
21132        final String action = intent.getAction();
21133        if (isProtectedBroadcast
21134                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
21135                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
21136                || Intent.ACTION_MEDIA_BUTTON.equals(action)
21137                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
21138                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
21139                || Intent.ACTION_MASTER_CLEAR.equals(action)
21140                || Intent.ACTION_FACTORY_RESET.equals(action)
21141                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
21142                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
21143                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
21144                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
21145                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
21146                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
21147                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
21148            // Broadcast is either protected, or it's a public action that
21149            // we've relaxed, so it's fine for system internals to send.
21150            return;
21151        }
21152
21153        // This broadcast may be a problem...  but there are often system components that
21154        // want to send an internal broadcast to themselves, which is annoying to have to
21155        // explicitly list each action as a protected broadcast, so we will check for that
21156        // one safe case and allow it: an explicit broadcast, only being received by something
21157        // that has protected itself.
21158        if (intent.getPackage() != null || intent.getComponent() != null) {
21159            if (receivers == null || receivers.size() == 0) {
21160                // Intent is explicit and there's no receivers.
21161                // This happens, e.g. , when a system component sends a broadcast to
21162                // its own runtime receiver, and there's no manifest receivers for it,
21163                // because this method is called twice for each broadcast,
21164                // for runtime receivers and manifest receivers and the later check would find
21165                // no receivers.
21166                return;
21167            }
21168            boolean allProtected = true;
21169            for (int i = receivers.size()-1; i >= 0; i--) {
21170                Object target = receivers.get(i);
21171                if (target instanceof ResolveInfo) {
21172                    ResolveInfo ri = (ResolveInfo)target;
21173                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
21174                        allProtected = false;
21175                        break;
21176                    }
21177                } else {
21178                    BroadcastFilter bf = (BroadcastFilter)target;
21179                    if (bf.requiredPermission == null) {
21180                        allProtected = false;
21181                        break;
21182                    }
21183                }
21184            }
21185            if (allProtected) {
21186                // All safe!
21187                return;
21188            }
21189        }
21190
21191        // The vast majority of broadcasts sent from system internals
21192        // should be protected to avoid security holes, so yell loudly
21193        // to ensure we examine these cases.
21194        if (callerApp != null) {
21195            Log.wtf(TAG, "Sending non-protected broadcast " + action
21196                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
21197                    new Throwable());
21198        } else {
21199            Log.wtf(TAG, "Sending non-protected broadcast " + action
21200                            + " from system uid " + UserHandle.formatUid(callingUid)
21201                            + " pkg " + callerPackage,
21202                    new Throwable());
21203        }
21204    }
21205
21206    @GuardedBy("this")
21207    final int broadcastIntentLocked(ProcessRecord callerApp,
21208            String callerPackage, Intent intent, String resolvedType,
21209            IIntentReceiver resultTo, int resultCode, String resultData,
21210            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
21211            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
21212        intent = new Intent(intent);
21213
21214        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
21215        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
21216        if (callerInstantApp) {
21217            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21218        }
21219
21220        // By default broadcasts do not go to stopped apps.
21221        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
21222
21223        // If we have not finished booting, don't allow this to launch new processes.
21224        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
21225            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21226        }
21227
21228        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
21229                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
21230                + " ordered=" + ordered + " userid=" + userId);
21231        if ((resultTo != null) && !ordered) {
21232            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
21233        }
21234
21235        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
21236                ALLOW_NON_FULL, "broadcast", callerPackage);
21237
21238        // Make sure that the user who is receiving this broadcast or its parent is running.
21239        // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
21240        if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
21241            if ((callingUid != SYSTEM_UID
21242                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
21243                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
21244                Slog.w(TAG, "Skipping broadcast of " + intent
21245                        + ": user " + userId + " and its parent (if any) are stopped");
21246                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
21247            }
21248        }
21249
21250        final String action = intent.getAction();
21251        BroadcastOptions brOptions = null;
21252        if (bOptions != null) {
21253            brOptions = new BroadcastOptions(bOptions);
21254            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
21255                // See if the caller is allowed to do this.  Note we are checking against
21256                // the actual real caller (not whoever provided the operation as say a
21257                // PendingIntent), because that who is actually supplied the arguments.
21258                if (checkComponentPermission(
21259                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
21260                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
21261                        != PackageManager.PERMISSION_GRANTED) {
21262                    String msg = "Permission Denial: " + intent.getAction()
21263                            + " broadcast from " + callerPackage + " (pid=" + callingPid
21264                            + ", uid=" + callingUid + ")"
21265                            + " requires "
21266                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21267                    Slog.w(TAG, msg);
21268                    throw new SecurityException(msg);
21269                }
21270            }
21271            if (brOptions.isDontSendToRestrictedApps()
21272                    && !isUidActiveLocked(callingUid)
21273                    && isBackgroundRestrictedNoCheck(callingUid, callerPackage)) {
21274                Slog.i(TAG, "Not sending broadcast " + action + " - app " + callerPackage
21275                        + " has background restrictions");
21276                return ActivityManager.START_CANCELED;
21277            }
21278        }
21279
21280        // Verify that protected broadcasts are only being sent by system code,
21281        // and that system code is only sending protected broadcasts.
21282        final boolean isProtectedBroadcast;
21283        try {
21284            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
21285        } catch (RemoteException e) {
21286            Slog.w(TAG, "Remote exception", e);
21287            return ActivityManager.BROADCAST_SUCCESS;
21288        }
21289
21290        final boolean isCallerSystem;
21291        switch (UserHandle.getAppId(callingUid)) {
21292            case ROOT_UID:
21293            case SYSTEM_UID:
21294            case PHONE_UID:
21295            case BLUETOOTH_UID:
21296            case NFC_UID:
21297            case SE_UID:
21298                isCallerSystem = true;
21299                break;
21300            default:
21301                isCallerSystem = (callerApp != null) && callerApp.persistent;
21302                break;
21303        }
21304
21305        // First line security check before anything else: stop non-system apps from
21306        // sending protected broadcasts.
21307        if (!isCallerSystem) {
21308            if (isProtectedBroadcast) {
21309                String msg = "Permission Denial: not allowed to send broadcast "
21310                        + action + " from pid="
21311                        + callingPid + ", uid=" + callingUid;
21312                Slog.w(TAG, msg);
21313                throw new SecurityException(msg);
21314
21315            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
21316                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
21317                // Special case for compatibility: we don't want apps to send this,
21318                // but historically it has not been protected and apps may be using it
21319                // to poke their own app widget.  So, instead of making it protected,
21320                // just limit it to the caller.
21321                if (callerPackage == null) {
21322                    String msg = "Permission Denial: not allowed to send broadcast "
21323                            + action + " from unknown caller.";
21324                    Slog.w(TAG, msg);
21325                    throw new SecurityException(msg);
21326                } else if (intent.getComponent() != null) {
21327                    // They are good enough to send to an explicit component...  verify
21328                    // it is being sent to the calling app.
21329                    if (!intent.getComponent().getPackageName().equals(
21330                            callerPackage)) {
21331                        String msg = "Permission Denial: not allowed to send broadcast "
21332                                + action + " to "
21333                                + intent.getComponent().getPackageName() + " from "
21334                                + callerPackage;
21335                        Slog.w(TAG, msg);
21336                        throw new SecurityException(msg);
21337                    }
21338                } else {
21339                    // Limit broadcast to their own package.
21340                    intent.setPackage(callerPackage);
21341                }
21342            }
21343        }
21344
21345        if (action != null) {
21346            if (getBackgroundLaunchBroadcasts().contains(action)) {
21347                if (DEBUG_BACKGROUND_CHECK) {
21348                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
21349                }
21350                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
21351            }
21352
21353            switch (action) {
21354                case Intent.ACTION_UID_REMOVED:
21355                case Intent.ACTION_PACKAGE_REMOVED:
21356                case Intent.ACTION_PACKAGE_CHANGED:
21357                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21358                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21359                case Intent.ACTION_PACKAGES_SUSPENDED:
21360                case Intent.ACTION_PACKAGES_UNSUSPENDED:
21361                    // Handle special intents: if this broadcast is from the package
21362                    // manager about a package being removed, we need to remove all of
21363                    // its activities from the history stack.
21364                    if (checkComponentPermission(
21365                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
21366                            callingPid, callingUid, -1, true)
21367                            != PackageManager.PERMISSION_GRANTED) {
21368                        String msg = "Permission Denial: " + intent.getAction()
21369                                + " broadcast from " + callerPackage + " (pid=" + callingPid
21370                                + ", uid=" + callingUid + ")"
21371                                + " requires "
21372                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
21373                        Slog.w(TAG, msg);
21374                        throw new SecurityException(msg);
21375                    }
21376                    switch (action) {
21377                        case Intent.ACTION_UID_REMOVED:
21378                            final int uid = getUidFromIntent(intent);
21379                            if (uid >= 0) {
21380                                mBatteryStatsService.removeUid(uid);
21381                                mAppOpsService.uidRemoved(uid);
21382                            }
21383                            break;
21384                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21385                            // If resources are unavailable just force stop all those packages
21386                            // and flush the attribute cache as well.
21387                            String list[] =
21388                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21389                            if (list != null && list.length > 0) {
21390                                for (int i = 0; i < list.length; i++) {
21391                                    forceStopPackageLocked(list[i], -1, false, true, true,
21392                                            false, false, userId, "storage unmount");
21393                                }
21394                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21395                                sendPackageBroadcastLocked(
21396                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
21397                                        list, userId);
21398                            }
21399                            break;
21400                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21401                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21402                            break;
21403                        case Intent.ACTION_PACKAGE_REMOVED:
21404                        case Intent.ACTION_PACKAGE_CHANGED:
21405                            Uri data = intent.getData();
21406                            String ssp;
21407                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
21408                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
21409                                final boolean replacing =
21410                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21411                                final boolean killProcess =
21412                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
21413                                final boolean fullUninstall = removed && !replacing;
21414                                if (removed) {
21415                                    if (killProcess) {
21416                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
21417                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
21418                                                false, true, true, false, fullUninstall, userId,
21419                                                removed ? "pkg removed" : "pkg changed");
21420                                    }
21421                                    final int cmd = killProcess
21422                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
21423                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
21424                                    sendPackageBroadcastLocked(cmd,
21425                                            new String[] {ssp}, userId);
21426                                    if (fullUninstall) {
21427                                        mAppOpsService.packageRemoved(
21428                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
21429
21430                                        // Remove all permissions granted from/to this package
21431                                        removeUriPermissionsForPackageLocked(ssp, userId, true,
21432                                                false);
21433
21434                                        mRecentTasks.removeTasksByPackageName(ssp, userId);
21435
21436                                        mServices.forceStopPackageLocked(ssp, userId);
21437                                        mAppWarnings.onPackageUninstalled(ssp);
21438                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
21439                                        mBatteryStatsService.notePackageUninstalled(ssp);
21440                                    }
21441                                } else {
21442                                    if (killProcess) {
21443                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
21444                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
21445                                                userId, ProcessList.INVALID_ADJ,
21446                                                false, true, true, false, "change " + ssp);
21447                                    }
21448                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
21449                                            intent.getStringArrayExtra(
21450                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
21451                                }
21452                            }
21453                            break;
21454                        case Intent.ACTION_PACKAGES_SUSPENDED:
21455                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
21456                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
21457                                    intent.getAction());
21458                            final String[] packageNames = intent.getStringArrayExtra(
21459                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
21460                            final int userHandle = intent.getIntExtra(
21461                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
21462
21463                            synchronized(ActivityManagerService.this) {
21464                                mRecentTasks.onPackagesSuspendedChanged(
21465                                        packageNames, suspended, userHandle);
21466                            }
21467                            break;
21468                    }
21469                    break;
21470                case Intent.ACTION_PACKAGE_REPLACED:
21471                {
21472                    final Uri data = intent.getData();
21473                    final String ssp;
21474                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21475                        ApplicationInfo aInfo = null;
21476                        try {
21477                            aInfo = AppGlobals.getPackageManager()
21478                                    .getApplicationInfo(ssp, STOCK_PM_FLAGS, userId);
21479                        } catch (RemoteException ignore) {}
21480                        if (aInfo == null) {
21481                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
21482                                    + " ssp=" + ssp + " data=" + data);
21483                            return ActivityManager.BROADCAST_SUCCESS;
21484                        }
21485                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
21486                        mServices.updateServiceApplicationInfoLocked(aInfo);
21487                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
21488                                new String[] {ssp}, userId);
21489                    }
21490                    break;
21491                }
21492                case Intent.ACTION_PACKAGE_ADDED:
21493                {
21494                    // Special case for adding a package: by default turn on compatibility mode.
21495                    Uri data = intent.getData();
21496                    String ssp;
21497                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21498                        final boolean replacing =
21499                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21500                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
21501
21502                        try {
21503                            ApplicationInfo ai = AppGlobals.getPackageManager().
21504                                    getApplicationInfo(ssp, STOCK_PM_FLAGS, 0);
21505                            mBatteryStatsService.notePackageInstalled(ssp,
21506                                    ai != null ? ai.versionCode : 0);
21507                        } catch (RemoteException e) {
21508                        }
21509                    }
21510                    break;
21511                }
21512                case Intent.ACTION_PACKAGE_DATA_CLEARED:
21513                {
21514                    Uri data = intent.getData();
21515                    String ssp;
21516                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21517                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
21518                        mAppWarnings.onPackageDataCleared(ssp);
21519                    }
21520                    break;
21521                }
21522                case Intent.ACTION_TIMEZONE_CHANGED:
21523                    // If this is the time zone changed action, queue up a message that will reset
21524                    // the timezone of all currently running processes. This message will get
21525                    // queued up before the broadcast happens.
21526                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
21527                    break;
21528                case Intent.ACTION_TIME_CHANGED:
21529                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
21530                    // the tri-state value it may contain and "unknown".
21531                    // For convenience we re-use the Intent extra values.
21532                    final int NO_EXTRA_VALUE_FOUND = -1;
21533                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
21534                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
21535                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
21536                    // Only send a message if the time preference is available.
21537                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
21538                        Message updateTimePreferenceMsg =
21539                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
21540                                        timeFormatPreferenceMsgValue, 0);
21541                        mHandler.sendMessage(updateTimePreferenceMsg);
21542                    }
21543                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21544                    synchronized (stats) {
21545                        stats.noteCurrentTimeChangedLocked();
21546                    }
21547                    break;
21548                case Intent.ACTION_CLEAR_DNS_CACHE:
21549                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
21550                    break;
21551                case Proxy.PROXY_CHANGE_ACTION:
21552                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
21553                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
21554                    break;
21555                case android.hardware.Camera.ACTION_NEW_PICTURE:
21556                case android.hardware.Camera.ACTION_NEW_VIDEO:
21557                    // In N we just turned these off; in O we are turing them back on partly,
21558                    // only for registered receivers.  This will still address the main problem
21559                    // (a spam of apps waking up when a picture is taken putting significant
21560                    // memory pressure on the system at a bad point), while still allowing apps
21561                    // that are already actively running to know about this happening.
21562                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21563                    break;
21564                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
21565                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
21566                    break;
21567                case "com.android.launcher.action.INSTALL_SHORTCUT":
21568                    // As of O, we no longer support this broadcasts, even for pre-O apps.
21569                    // Apps should now be using ShortcutManager.pinRequestShortcut().
21570                    Log.w(TAG, "Broadcast " + action
21571                            + " no longer supported. It will not be delivered.");
21572                    return ActivityManager.BROADCAST_SUCCESS;
21573            }
21574
21575            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
21576                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
21577                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
21578                final int uid = getUidFromIntent(intent);
21579                if (uid != -1) {
21580                    final UidRecord uidRec = mActiveUids.get(uid);
21581                    if (uidRec != null) {
21582                        uidRec.updateHasInternetPermission();
21583                    }
21584                }
21585            }
21586        }
21587
21588        // Add to the sticky list if requested.
21589        if (sticky) {
21590            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
21591                    callingPid, callingUid)
21592                    != PackageManager.PERMISSION_GRANTED) {
21593                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
21594                        + callingPid + ", uid=" + callingUid
21595                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21596                Slog.w(TAG, msg);
21597                throw new SecurityException(msg);
21598            }
21599            if (requiredPermissions != null && requiredPermissions.length > 0) {
21600                Slog.w(TAG, "Can't broadcast sticky intent " + intent
21601                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
21602                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
21603            }
21604            if (intent.getComponent() != null) {
21605                throw new SecurityException(
21606                        "Sticky broadcasts can't target a specific component");
21607            }
21608            // We use userId directly here, since the "all" target is maintained
21609            // as a separate set of sticky broadcasts.
21610            if (userId != UserHandle.USER_ALL) {
21611                // But first, if this is not a broadcast to all users, then
21612                // make sure it doesn't conflict with an existing broadcast to
21613                // all users.
21614                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
21615                        UserHandle.USER_ALL);
21616                if (stickies != null) {
21617                    ArrayList<Intent> list = stickies.get(intent.getAction());
21618                    if (list != null) {
21619                        int N = list.size();
21620                        int i;
21621                        for (i=0; i<N; i++) {
21622                            if (intent.filterEquals(list.get(i))) {
21623                                throw new IllegalArgumentException(
21624                                        "Sticky broadcast " + intent + " for user "
21625                                        + userId + " conflicts with existing global broadcast");
21626                            }
21627                        }
21628                    }
21629                }
21630            }
21631            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21632            if (stickies == null) {
21633                stickies = new ArrayMap<>();
21634                mStickyBroadcasts.put(userId, stickies);
21635            }
21636            ArrayList<Intent> list = stickies.get(intent.getAction());
21637            if (list == null) {
21638                list = new ArrayList<>();
21639                stickies.put(intent.getAction(), list);
21640            }
21641            final int stickiesCount = list.size();
21642            int i;
21643            for (i = 0; i < stickiesCount; i++) {
21644                if (intent.filterEquals(list.get(i))) {
21645                    // This sticky already exists, replace it.
21646                    list.set(i, new Intent(intent));
21647                    break;
21648                }
21649            }
21650            if (i >= stickiesCount) {
21651                list.add(new Intent(intent));
21652            }
21653        }
21654
21655        int[] users;
21656        if (userId == UserHandle.USER_ALL) {
21657            // Caller wants broadcast to go to all started users.
21658            users = mUserController.getStartedUserArray();
21659        } else {
21660            // Caller wants broadcast to go to one specific user.
21661            users = new int[] {userId};
21662        }
21663
21664        // Figure out who all will receive this broadcast.
21665        List receivers = null;
21666        List<BroadcastFilter> registeredReceivers = null;
21667        // Need to resolve the intent to interested receivers...
21668        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
21669                 == 0) {
21670            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
21671        }
21672        if (intent.getComponent() == null) {
21673            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
21674                // Query one target user at a time, excluding shell-restricted users
21675                for (int i = 0; i < users.length; i++) {
21676                    if (mUserController.hasUserRestriction(
21677                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
21678                        continue;
21679                    }
21680                    List<BroadcastFilter> registeredReceiversForUser =
21681                            mReceiverResolver.queryIntent(intent,
21682                                    resolvedType, false /*defaultOnly*/, users[i]);
21683                    if (registeredReceivers == null) {
21684                        registeredReceivers = registeredReceiversForUser;
21685                    } else if (registeredReceiversForUser != null) {
21686                        registeredReceivers.addAll(registeredReceiversForUser);
21687                    }
21688                }
21689            } else {
21690                registeredReceivers = mReceiverResolver.queryIntent(intent,
21691                        resolvedType, false /*defaultOnly*/, userId);
21692            }
21693        }
21694
21695        final boolean replacePending =
21696                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
21697
21698        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
21699                + " replacePending=" + replacePending);
21700
21701        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
21702        if (!ordered && NR > 0) {
21703            // If we are not serializing this broadcast, then send the
21704            // registered receivers separately so they don't wait for the
21705            // components to be launched.
21706            if (isCallerSystem) {
21707                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21708                        isProtectedBroadcast, registeredReceivers);
21709            }
21710            final BroadcastQueue queue = broadcastQueueForIntent(intent);
21711            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21712                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21713                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
21714                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
21715            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
21716            final boolean replaced = replacePending
21717                    && (queue.replaceParallelBroadcastLocked(r) != null);
21718            // Note: We assume resultTo is null for non-ordered broadcasts.
21719            if (!replaced) {
21720                queue.enqueueParallelBroadcastLocked(r);
21721                queue.scheduleBroadcastsLocked();
21722            }
21723            registeredReceivers = null;
21724            NR = 0;
21725        }
21726
21727        // Merge into one list.
21728        int ir = 0;
21729        if (receivers != null) {
21730            // A special case for PACKAGE_ADDED: do not allow the package
21731            // being added to see this broadcast.  This prevents them from
21732            // using this as a back door to get run as soon as they are
21733            // installed.  Maybe in the future we want to have a special install
21734            // broadcast or such for apps, but we'd like to deliberately make
21735            // this decision.
21736            String skipPackages[] = null;
21737            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
21738                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
21739                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
21740                Uri data = intent.getData();
21741                if (data != null) {
21742                    String pkgName = data.getSchemeSpecificPart();
21743                    if (pkgName != null) {
21744                        skipPackages = new String[] { pkgName };
21745                    }
21746                }
21747            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
21748                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21749            }
21750            if (skipPackages != null && (skipPackages.length > 0)) {
21751                for (String skipPackage : skipPackages) {
21752                    if (skipPackage != null) {
21753                        int NT = receivers.size();
21754                        for (int it=0; it<NT; it++) {
21755                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
21756                            if (curt.activityInfo.packageName.equals(skipPackage)) {
21757                                receivers.remove(it);
21758                                it--;
21759                                NT--;
21760                            }
21761                        }
21762                    }
21763                }
21764            }
21765
21766            int NT = receivers != null ? receivers.size() : 0;
21767            int it = 0;
21768            ResolveInfo curt = null;
21769            BroadcastFilter curr = null;
21770            while (it < NT && ir < NR) {
21771                if (curt == null) {
21772                    curt = (ResolveInfo)receivers.get(it);
21773                }
21774                if (curr == null) {
21775                    curr = registeredReceivers.get(ir);
21776                }
21777                if (curr.getPriority() >= curt.priority) {
21778                    // Insert this broadcast record into the final list.
21779                    receivers.add(it, curr);
21780                    ir++;
21781                    curr = null;
21782                    it++;
21783                    NT++;
21784                } else {
21785                    // Skip to the next ResolveInfo in the final list.
21786                    it++;
21787                    curt = null;
21788                }
21789            }
21790        }
21791        while (ir < NR) {
21792            if (receivers == null) {
21793                receivers = new ArrayList();
21794            }
21795            receivers.add(registeredReceivers.get(ir));
21796            ir++;
21797        }
21798
21799        if (isCallerSystem) {
21800            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21801                    isProtectedBroadcast, receivers);
21802        }
21803
21804        if ((receivers != null && receivers.size() > 0)
21805                || resultTo != null) {
21806            BroadcastQueue queue = broadcastQueueForIntent(intent);
21807            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21808                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21809                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
21810                    resultData, resultExtras, ordered, sticky, false, userId);
21811
21812            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
21813                    + ": prev had " + queue.mOrderedBroadcasts.size());
21814            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
21815                    "Enqueueing broadcast " + r.intent.getAction());
21816
21817            final BroadcastRecord oldRecord =
21818                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
21819            if (oldRecord != null) {
21820                // Replaced, fire the result-to receiver.
21821                if (oldRecord.resultTo != null) {
21822                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
21823                    try {
21824                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
21825                                oldRecord.intent,
21826                                Activity.RESULT_CANCELED, null, null,
21827                                false, false, oldRecord.userId);
21828                    } catch (RemoteException e) {
21829                        Slog.w(TAG, "Failure ["
21830                                + queue.mQueueName + "] sending broadcast result of "
21831                                + intent, e);
21832
21833                    }
21834                }
21835            } else {
21836                queue.enqueueOrderedBroadcastLocked(r);
21837                queue.scheduleBroadcastsLocked();
21838            }
21839        } else {
21840            // There was nobody interested in the broadcast, but we still want to record
21841            // that it happened.
21842            if (intent.getComponent() == null && intent.getPackage() == null
21843                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21844                // This was an implicit broadcast... let's record it for posterity.
21845                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
21846            }
21847        }
21848
21849        return ActivityManager.BROADCAST_SUCCESS;
21850    }
21851
21852    /**
21853     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
21854     */
21855    private int getUidFromIntent(Intent intent) {
21856        if (intent == null) {
21857            return -1;
21858        }
21859        final Bundle intentExtras = intent.getExtras();
21860        return intent.hasExtra(Intent.EXTRA_UID)
21861                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
21862    }
21863
21864    final void rotateBroadcastStatsIfNeededLocked() {
21865        final long now = SystemClock.elapsedRealtime();
21866        if (mCurBroadcastStats == null ||
21867                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
21868            mLastBroadcastStats = mCurBroadcastStats;
21869            if (mLastBroadcastStats != null) {
21870                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
21871                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
21872            }
21873            mCurBroadcastStats = new BroadcastStats();
21874        }
21875    }
21876
21877    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
21878            int skipCount, long dispatchTime) {
21879        rotateBroadcastStatsIfNeededLocked();
21880        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
21881    }
21882
21883    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
21884        rotateBroadcastStatsIfNeededLocked();
21885        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
21886    }
21887
21888    final Intent verifyBroadcastLocked(Intent intent) {
21889        // Refuse possible leaked file descriptors
21890        if (intent != null && intent.hasFileDescriptors() == true) {
21891            throw new IllegalArgumentException("File descriptors passed in Intent");
21892        }
21893
21894        int flags = intent.getFlags();
21895
21896        if (!mProcessesReady) {
21897            // if the caller really truly claims to know what they're doing, go
21898            // ahead and allow the broadcast without launching any receivers
21899            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
21900                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
21901            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21902                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
21903                        + " before boot completion");
21904                throw new IllegalStateException("Cannot broadcast before boot completed");
21905            }
21906        }
21907
21908        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
21909            throw new IllegalArgumentException(
21910                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
21911        }
21912
21913        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21914            switch (Binder.getCallingUid()) {
21915                case ROOT_UID:
21916                case SHELL_UID:
21917                    break;
21918                default:
21919                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
21920                            + Binder.getCallingUid());
21921                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
21922                    break;
21923            }
21924        }
21925
21926        return intent;
21927    }
21928
21929    public final int broadcastIntent(IApplicationThread caller,
21930            Intent intent, String resolvedType, IIntentReceiver resultTo,
21931            int resultCode, String resultData, Bundle resultExtras,
21932            String[] requiredPermissions, int appOp, Bundle bOptions,
21933            boolean serialized, boolean sticky, int userId) {
21934        enforceNotIsolatedCaller("broadcastIntent");
21935        synchronized(this) {
21936            intent = verifyBroadcastLocked(intent);
21937
21938            final ProcessRecord callerApp = getRecordForAppLocked(caller);
21939            final int callingPid = Binder.getCallingPid();
21940            final int callingUid = Binder.getCallingUid();
21941            final long origId = Binder.clearCallingIdentity();
21942            int res = broadcastIntentLocked(callerApp,
21943                    callerApp != null ? callerApp.info.packageName : null,
21944                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
21945                    requiredPermissions, appOp, bOptions, serialized, sticky,
21946                    callingPid, callingUid, userId);
21947            Binder.restoreCallingIdentity(origId);
21948            return res;
21949        }
21950    }
21951
21952
21953    int broadcastIntentInPackage(String packageName, int uid,
21954            Intent intent, String resolvedType, IIntentReceiver resultTo,
21955            int resultCode, String resultData, Bundle resultExtras,
21956            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
21957            int userId) {
21958        synchronized(this) {
21959            intent = verifyBroadcastLocked(intent);
21960
21961            final long origId = Binder.clearCallingIdentity();
21962            String[] requiredPermissions = requiredPermission == null ? null
21963                    : new String[] {requiredPermission};
21964            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
21965                    resultTo, resultCode, resultData, resultExtras,
21966                    requiredPermissions, OP_NONE, bOptions, serialized,
21967                    sticky, -1, uid, userId);
21968            Binder.restoreCallingIdentity(origId);
21969            return res;
21970        }
21971    }
21972
21973    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
21974        // Refuse possible leaked file descriptors
21975        if (intent != null && intent.hasFileDescriptors() == true) {
21976            throw new IllegalArgumentException("File descriptors passed in Intent");
21977        }
21978
21979        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21980                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
21981
21982        synchronized(this) {
21983            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
21984                    != PackageManager.PERMISSION_GRANTED) {
21985                String msg = "Permission Denial: unbroadcastIntent() from pid="
21986                        + Binder.getCallingPid()
21987                        + ", uid=" + Binder.getCallingUid()
21988                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21989                Slog.w(TAG, msg);
21990                throw new SecurityException(msg);
21991            }
21992            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21993            if (stickies != null) {
21994                ArrayList<Intent> list = stickies.get(intent.getAction());
21995                if (list != null) {
21996                    int N = list.size();
21997                    int i;
21998                    for (i=0; i<N; i++) {
21999                        if (intent.filterEquals(list.get(i))) {
22000                            list.remove(i);
22001                            break;
22002                        }
22003                    }
22004                    if (list.size() <= 0) {
22005                        stickies.remove(intent.getAction());
22006                    }
22007                }
22008                if (stickies.size() <= 0) {
22009                    mStickyBroadcasts.remove(userId);
22010                }
22011            }
22012        }
22013    }
22014
22015    void backgroundServicesFinishedLocked(int userId) {
22016        for (BroadcastQueue queue : mBroadcastQueues) {
22017            queue.backgroundServicesFinishedLocked(userId);
22018        }
22019    }
22020
22021    public void finishReceiver(IBinder who, int resultCode, String resultData,
22022            Bundle resultExtras, boolean resultAbort, int flags) {
22023        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
22024
22025        // Refuse possible leaked file descriptors
22026        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
22027            throw new IllegalArgumentException("File descriptors passed in Bundle");
22028        }
22029
22030        final long origId = Binder.clearCallingIdentity();
22031        try {
22032            boolean doNext = false;
22033            BroadcastRecord r;
22034
22035            synchronized(this) {
22036                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
22037                        ? mFgBroadcastQueue : mBgBroadcastQueue;
22038                r = queue.getMatchingOrderedReceiver(who);
22039                if (r != null) {
22040                    doNext = r.queue.finishReceiverLocked(r, resultCode,
22041                        resultData, resultExtras, resultAbort, true);
22042                }
22043                if (doNext) {
22044                    r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
22045                }
22046                // updateOomAdjLocked() will be done here
22047                trimApplicationsLocked();
22048            }
22049
22050        } finally {
22051            Binder.restoreCallingIdentity(origId);
22052        }
22053    }
22054
22055    // =========================================================
22056    // INSTRUMENTATION
22057    // =========================================================
22058
22059    public boolean startInstrumentation(ComponentName className,
22060            String profileFile, int flags, Bundle arguments,
22061            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
22062            int userId, String abiOverride) {
22063        enforceNotIsolatedCaller("startInstrumentation");
22064        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22065                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
22066        // Refuse possible leaked file descriptors
22067        if (arguments != null && arguments.hasFileDescriptors()) {
22068            throw new IllegalArgumentException("File descriptors passed in Bundle");
22069        }
22070
22071        synchronized(this) {
22072            InstrumentationInfo ii = null;
22073            ApplicationInfo ai = null;
22074            try {
22075                ii = mContext.getPackageManager().getInstrumentationInfo(
22076                    className, STOCK_PM_FLAGS);
22077                ai = AppGlobals.getPackageManager().getApplicationInfo(
22078                        ii.targetPackage, STOCK_PM_FLAGS, userId);
22079            } catch (PackageManager.NameNotFoundException e) {
22080            } catch (RemoteException e) {
22081            }
22082            if (ii == null) {
22083                reportStartInstrumentationFailureLocked(watcher, className,
22084                        "Unable to find instrumentation info for: " + className);
22085                return false;
22086            }
22087            if (ai == null) {
22088                reportStartInstrumentationFailureLocked(watcher, className,
22089                        "Unable to find instrumentation target package: " + ii.targetPackage);
22090                return false;
22091            }
22092            if (!ai.hasCode()) {
22093                reportStartInstrumentationFailureLocked(watcher, className,
22094                        "Instrumentation target has no code: " + ii.targetPackage);
22095                return false;
22096            }
22097
22098            int match = mContext.getPackageManager().checkSignatures(
22099                    ii.targetPackage, ii.packageName);
22100            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
22101                String msg = "Permission Denial: starting instrumentation "
22102                        + className + " from pid="
22103                        + Binder.getCallingPid()
22104                        + ", uid=" + Binder.getCallingPid()
22105                        + " not allowed because package " + ii.packageName
22106                        + " does not have a signature matching the target "
22107                        + ii.targetPackage;
22108                reportStartInstrumentationFailureLocked(watcher, className, msg);
22109                throw new SecurityException(msg);
22110            }
22111
22112            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
22113            activeInstr.mClass = className;
22114            String defProcess = ai.processName;;
22115            if (ii.targetProcesses == null) {
22116                activeInstr.mTargetProcesses = new String[]{ai.processName};
22117            } else if (ii.targetProcesses.equals("*")) {
22118                activeInstr.mTargetProcesses = new String[0];
22119            } else {
22120                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
22121                defProcess = activeInstr.mTargetProcesses[0];
22122            }
22123            activeInstr.mTargetInfo = ai;
22124            activeInstr.mProfileFile = profileFile;
22125            activeInstr.mArguments = arguments;
22126            activeInstr.mWatcher = watcher;
22127            activeInstr.mUiAutomationConnection = uiAutomationConnection;
22128            activeInstr.mResultClass = className;
22129
22130            boolean disableHiddenApiChecks =
22131                    (flags & INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
22132            if (disableHiddenApiChecks) {
22133                enforceCallingPermission(android.Manifest.permission.DISABLE_HIDDEN_API_CHECKS,
22134                        "disable hidden API checks");
22135            }
22136
22137            final long origId = Binder.clearCallingIdentity();
22138            // Instrumentation can kill and relaunch even persistent processes
22139            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
22140                    "start instr");
22141            // Inform usage stats to make the target package active
22142            if (mUsageStatsService != null) {
22143                mUsageStatsService.reportEvent(ii.targetPackage, userId,
22144                        UsageEvents.Event.SYSTEM_INTERACTION);
22145            }
22146
22147            ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
22148                    abiOverride);
22149            app.instr = activeInstr;
22150            activeInstr.mFinished = false;
22151            activeInstr.mRunningProcesses.add(app);
22152            if (!mActiveInstrumentation.contains(activeInstr)) {
22153                mActiveInstrumentation.add(activeInstr);
22154            }
22155            Binder.restoreCallingIdentity(origId);
22156        }
22157
22158        return true;
22159    }
22160
22161    /**
22162     * Report errors that occur while attempting to start Instrumentation.  Always writes the
22163     * error to the logs, but if somebody is watching, send the report there too.  This enables
22164     * the "am" command to report errors with more information.
22165     *
22166     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
22167     * @param cn The component name of the instrumentation.
22168     * @param report The error report.
22169     */
22170    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
22171            ComponentName cn, String report) {
22172        Slog.w(TAG, report);
22173        if (watcher != null) {
22174            Bundle results = new Bundle();
22175            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
22176            results.putString("Error", report);
22177            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
22178        }
22179    }
22180
22181    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
22182        if (app.instr == null) {
22183            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
22184            return;
22185        }
22186
22187        if (!app.instr.mFinished && results != null) {
22188            if (app.instr.mCurResults == null) {
22189                app.instr.mCurResults = new Bundle(results);
22190            } else {
22191                app.instr.mCurResults.putAll(results);
22192            }
22193        }
22194    }
22195
22196    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
22197        int userId = UserHandle.getCallingUserId();
22198        // Refuse possible leaked file descriptors
22199        if (results != null && results.hasFileDescriptors()) {
22200            throw new IllegalArgumentException("File descriptors passed in Intent");
22201        }
22202
22203        synchronized(this) {
22204            ProcessRecord app = getRecordForAppLocked(target);
22205            if (app == null) {
22206                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
22207                return;
22208            }
22209            final long origId = Binder.clearCallingIdentity();
22210            addInstrumentationResultsLocked(app, results);
22211            Binder.restoreCallingIdentity(origId);
22212        }
22213    }
22214
22215    @GuardedBy("this")
22216    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
22217        if (app.instr == null) {
22218            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
22219            return;
22220        }
22221
22222        if (!app.instr.mFinished) {
22223            if (app.instr.mWatcher != null) {
22224                Bundle finalResults = app.instr.mCurResults;
22225                if (finalResults != null) {
22226                    if (app.instr.mCurResults != null && results != null) {
22227                        finalResults.putAll(results);
22228                    }
22229                } else {
22230                    finalResults = results;
22231                }
22232                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
22233                        app.instr.mClass, resultCode, finalResults);
22234            }
22235
22236            // Can't call out of the system process with a lock held, so post a message.
22237            if (app.instr.mUiAutomationConnection != null) {
22238                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
22239                        app.instr.mUiAutomationConnection).sendToTarget();
22240            }
22241            app.instr.mFinished = true;
22242        }
22243
22244        app.instr.removeProcess(app);
22245        app.instr = null;
22246
22247        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
22248                "finished inst");
22249    }
22250
22251    public void finishInstrumentation(IApplicationThread target,
22252            int resultCode, Bundle results) {
22253        int userId = UserHandle.getCallingUserId();
22254        // Refuse possible leaked file descriptors
22255        if (results != null && results.hasFileDescriptors()) {
22256            throw new IllegalArgumentException("File descriptors passed in Intent");
22257        }
22258
22259        synchronized(this) {
22260            ProcessRecord app = getRecordForAppLocked(target);
22261            if (app == null) {
22262                Slog.w(TAG, "finishInstrumentation: no app for " + target);
22263                return;
22264            }
22265            final long origId = Binder.clearCallingIdentity();
22266            finishInstrumentationLocked(app, resultCode, results);
22267            Binder.restoreCallingIdentity(origId);
22268        }
22269    }
22270
22271    // =========================================================
22272    // CONFIGURATION
22273    // =========================================================
22274
22275    public ConfigurationInfo getDeviceConfigurationInfo() {
22276        ConfigurationInfo config = new ConfigurationInfo();
22277        synchronized (this) {
22278            final Configuration globalConfig = getGlobalConfiguration();
22279            config.reqTouchScreen = globalConfig.touchscreen;
22280            config.reqKeyboardType = globalConfig.keyboard;
22281            config.reqNavigation = globalConfig.navigation;
22282            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
22283                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
22284                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
22285            }
22286            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
22287                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
22288                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
22289            }
22290            config.reqGlEsVersion = GL_ES_VERSION;
22291        }
22292        return config;
22293    }
22294
22295    ActivityStack getFocusedStack() {
22296        return mStackSupervisor.getFocusedStack();
22297    }
22298
22299    @Override
22300    public StackInfo getFocusedStackInfo() throws RemoteException {
22301        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
22302        long ident = Binder.clearCallingIdentity();
22303        try {
22304            synchronized (this) {
22305                ActivityStack focusedStack = getFocusedStack();
22306                if (focusedStack != null) {
22307                    return mStackSupervisor.getStackInfo(focusedStack.mStackId);
22308                }
22309                return null;
22310            }
22311        } finally {
22312            Binder.restoreCallingIdentity(ident);
22313        }
22314    }
22315
22316    public Configuration getConfiguration() {
22317        Configuration ci;
22318        synchronized(this) {
22319            ci = new Configuration(getGlobalConfiguration());
22320            ci.userSetLocale = false;
22321        }
22322        return ci;
22323    }
22324
22325    @Override
22326    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
22327        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
22328        synchronized (this) {
22329            mSuppressResizeConfigChanges = suppress;
22330        }
22331    }
22332
22333    /**
22334     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
22335     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
22336     *       activity and clearing the task at the same time.
22337     */
22338    @Override
22339    // TODO: API should just be about changing windowing modes...
22340    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
22341        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
22342                "moveTasksToFullscreenStack()");
22343        synchronized (this) {
22344            final long origId = Binder.clearCallingIdentity();
22345            try {
22346                final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
22347                if (stack != null){
22348                    if (!stack.isActivityTypeStandardOrUndefined()) {
22349                        throw new IllegalArgumentException(
22350                                "You can't move tasks from non-standard stacks.");
22351                    }
22352                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
22353                }
22354            } finally {
22355                Binder.restoreCallingIdentity(origId);
22356            }
22357        }
22358    }
22359
22360    @Override
22361    public void updatePersistentConfiguration(Configuration values) {
22362        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
22363        enforceWriteSettingsPermission("updatePersistentConfiguration()");
22364        if (values == null) {
22365            throw new NullPointerException("Configuration must not be null");
22366        }
22367
22368        int userId = UserHandle.getCallingUserId();
22369
22370        synchronized(this) {
22371            updatePersistentConfigurationLocked(values, userId);
22372        }
22373    }
22374
22375    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
22376        final long origId = Binder.clearCallingIdentity();
22377        try {
22378            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
22379        } finally {
22380            Binder.restoreCallingIdentity(origId);
22381        }
22382    }
22383
22384    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
22385        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
22386                FONT_SCALE, 1.0f, userId);
22387
22388        synchronized (this) {
22389            if (getGlobalConfiguration().fontScale == scaleFactor) {
22390                return;
22391            }
22392
22393            final Configuration configuration
22394                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22395            configuration.fontScale = scaleFactor;
22396            updatePersistentConfigurationLocked(configuration, userId);
22397        }
22398    }
22399
22400    private void enforceWriteSettingsPermission(String func) {
22401        int uid = Binder.getCallingUid();
22402        if (uid == ROOT_UID) {
22403            return;
22404        }
22405
22406        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
22407                Settings.getPackageNameForUid(mContext, uid), false)) {
22408            return;
22409        }
22410
22411        String msg = "Permission Denial: " + func + " from pid="
22412                + Binder.getCallingPid()
22413                + ", uid=" + uid
22414                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
22415        Slog.w(TAG, msg);
22416        throw new SecurityException(msg);
22417    }
22418
22419    @Override
22420    public boolean updateConfiguration(Configuration values) {
22421        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
22422
22423        synchronized(this) {
22424            if (values == null && mWindowManager != null) {
22425                // sentinel: fetch the current configuration from the window manager
22426                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22427            }
22428
22429            if (mWindowManager != null) {
22430                // Update OOM levels based on display size.
22431                mProcessList.applyDisplaySize(mWindowManager);
22432            }
22433
22434            final long origId = Binder.clearCallingIdentity();
22435            try {
22436                if (values != null) {
22437                    Settings.System.clearConfiguration(values);
22438                }
22439                updateConfigurationLocked(values, null, false, false /* persistent */,
22440                        UserHandle.USER_NULL, false /* deferResume */,
22441                        mTmpUpdateConfigurationResult);
22442                return mTmpUpdateConfigurationResult.changes != 0;
22443            } finally {
22444                Binder.restoreCallingIdentity(origId);
22445            }
22446        }
22447    }
22448
22449    void updateUserConfigurationLocked() {
22450        final Configuration configuration = new Configuration(getGlobalConfiguration());
22451        final int currentUserId = mUserController.getCurrentUserId();
22452        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
22453                currentUserId, Settings.System.canWrite(mContext));
22454        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
22455                false /* persistent */, currentUserId, false /* deferResume */);
22456    }
22457
22458    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22459            boolean initLocale) {
22460        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
22461    }
22462
22463    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22464            boolean initLocale, boolean deferResume) {
22465        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
22466        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
22467                UserHandle.USER_NULL, deferResume);
22468    }
22469
22470    // To cache the list of supported system locales
22471    private String[] mSupportedSystemLocales = null;
22472
22473    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22474            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
22475        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
22476                deferResume, null /* result */);
22477    }
22478
22479    /**
22480     * Do either or both things: (1) change the current configuration, and (2)
22481     * make sure the given activity is running with the (now) current
22482     * configuration.  Returns true if the activity has been left running, or
22483     * false if <var>starting</var> is being destroyed to match the new
22484     * configuration.
22485     *
22486     * @param userId is only used when persistent parameter is set to true to persist configuration
22487     *               for that particular user
22488     */
22489    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22490            boolean initLocale, boolean persistent, int userId, boolean deferResume,
22491            UpdateConfigurationResult result) {
22492        int changes = 0;
22493        boolean kept = true;
22494
22495        if (mWindowManager != null) {
22496            mWindowManager.deferSurfaceLayout();
22497        }
22498        try {
22499            if (values != null) {
22500                changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
22501                        deferResume);
22502            }
22503
22504            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22505        } finally {
22506            if (mWindowManager != null) {
22507                mWindowManager.continueSurfaceLayout();
22508            }
22509        }
22510
22511        if (result != null) {
22512            result.changes = changes;
22513            result.activityRelaunched = !kept;
22514        }
22515        return kept;
22516    }
22517
22518    /**
22519     * Returns true if this configuration change is interesting enough to send an
22520     * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
22521     */
22522    private static boolean isSplitConfigurationChange(int configDiff) {
22523        return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
22524    }
22525
22526    /** Update default (global) configuration and notify listeners about changes. */
22527    private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
22528            boolean persistent, int userId, boolean deferResume) {
22529        mTempConfig.setTo(getGlobalConfiguration());
22530        final int changes = mTempConfig.updateFrom(values);
22531        if (changes == 0) {
22532            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
22533            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
22534            // performDisplayOverrideConfigUpdate in order to send the new display configuration
22535            // (even if there are no actual changes) to unfreeze the window.
22536            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
22537            return 0;
22538        }
22539
22540        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
22541                "Updating global configuration to: " + values);
22542
22543        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
22544        StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
22545                values.colorMode,
22546                values.densityDpi,
22547                values.fontScale,
22548                values.hardKeyboardHidden,
22549                values.keyboard,
22550                values.keyboardHidden,
22551                values.mcc,
22552                values.mnc,
22553                values.navigation,
22554                values.navigationHidden,
22555                values.orientation,
22556                values.screenHeightDp,
22557                values.screenLayout,
22558                values.screenWidthDp,
22559                values.smallestScreenWidthDp,
22560                values.touchscreen,
22561                values.uiMode);
22562
22563
22564        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
22565            final LocaleList locales = values.getLocales();
22566            int bestLocaleIndex = 0;
22567            if (locales.size() > 1) {
22568                if (mSupportedSystemLocales == null) {
22569                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
22570                }
22571                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
22572            }
22573            SystemProperties.set("persist.sys.locale",
22574                    locales.get(bestLocaleIndex).toLanguageTag());
22575            LocaleList.setDefault(locales, bestLocaleIndex);
22576            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
22577                    locales.get(bestLocaleIndex)));
22578        }
22579
22580        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
22581        mTempConfig.seq = mConfigurationSeq;
22582
22583        // Update stored global config and notify everyone about the change.
22584        mStackSupervisor.onConfigurationChanged(mTempConfig);
22585
22586        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
22587        // TODO(multi-display): Update UsageEvents#Event to include displayId.
22588        mUsageStatsService.reportConfigurationChange(mTempConfig,
22589                mUserController.getCurrentUserId());
22590
22591        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
22592        updateShouldShowDialogsLocked(mTempConfig);
22593
22594        AttributeCache ac = AttributeCache.instance();
22595        if (ac != null) {
22596            ac.updateConfiguration(mTempConfig);
22597        }
22598
22599        // Make sure all resources in our process are updated right now, so that anyone who is going
22600        // to retrieve resource values after we return will be sure to get the new ones. This is
22601        // especially important during boot, where the first config change needs to guarantee all
22602        // resources have that config before following boot code is executed.
22603        mSystemThread.applyConfigurationToResources(mTempConfig);
22604
22605        // We need another copy of global config because we're scheduling some calls instead of
22606        // running them in place. We need to be sure that object we send will be handled unchanged.
22607        final Configuration configCopy = new Configuration(mTempConfig);
22608        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
22609            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
22610            msg.obj = configCopy;
22611            msg.arg1 = userId;
22612            mHandler.sendMessage(msg);
22613        }
22614
22615        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22616            ProcessRecord app = mLruProcesses.get(i);
22617            try {
22618                if (app.thread != null) {
22619                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
22620                            + app.processName + " new config " + configCopy);
22621                    mLifecycleManager.scheduleTransaction(app.thread,
22622                            ConfigurationChangeItem.obtain(configCopy));
22623                }
22624            } catch (Exception e) {
22625                Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
22626            }
22627        }
22628
22629        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
22630        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
22631                | Intent.FLAG_RECEIVER_FOREGROUND
22632                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22633        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22634                OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22635                UserHandle.USER_ALL);
22636        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
22637            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
22638            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
22639                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
22640                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22641            if (initLocale || !mProcessesReady) {
22642                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
22643            }
22644            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22645                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22646                    UserHandle.USER_ALL);
22647        }
22648
22649        // Send a broadcast to PackageInstallers if the configuration change is interesting
22650        // for the purposes of installing additional splits.
22651        if (!initLocale && isSplitConfigurationChange(changes)) {
22652            intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
22653            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
22654                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
22655
22656            // Typically only app stores will have this permission.
22657            String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
22658            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
22659                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
22660        }
22661
22662        // Override configuration of the default display duplicates global config, so we need to
22663        // update it also. This will also notify WindowManager about changes.
22664        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
22665                DEFAULT_DISPLAY);
22666
22667        return changes;
22668    }
22669
22670    @Override
22671    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
22672        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
22673
22674        synchronized (this) {
22675            // Check if display is initialized in AM.
22676            if (!mStackSupervisor.isDisplayAdded(displayId)) {
22677                // Call might come when display is not yet added or has already been removed.
22678                if (DEBUG_CONFIGURATION) {
22679                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
22680                            + displayId);
22681                }
22682                return false;
22683            }
22684
22685            if (values == null && mWindowManager != null) {
22686                // sentinel: fetch the current configuration from the window manager
22687                values = mWindowManager.computeNewConfiguration(displayId);
22688            }
22689
22690            if (mWindowManager != null) {
22691                // Update OOM levels based on display size.
22692                mProcessList.applyDisplaySize(mWindowManager);
22693            }
22694
22695            final long origId = Binder.clearCallingIdentity();
22696            try {
22697                if (values != null) {
22698                    Settings.System.clearConfiguration(values);
22699                }
22700                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
22701                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
22702                return mTmpUpdateConfigurationResult.changes != 0;
22703            } finally {
22704                Binder.restoreCallingIdentity(origId);
22705            }
22706        }
22707    }
22708
22709    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
22710            boolean deferResume, int displayId) {
22711        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
22712                displayId, null /* result */);
22713    }
22714
22715    /**
22716     * Updates override configuration specific for the selected display. If no config is provided,
22717     * new one will be computed in WM based on current display info.
22718     */
22719    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
22720            ActivityRecord starting, boolean deferResume, int displayId,
22721            UpdateConfigurationResult result) {
22722        int changes = 0;
22723        boolean kept = true;
22724
22725        if (mWindowManager != null) {
22726            mWindowManager.deferSurfaceLayout();
22727        }
22728        try {
22729            if (values != null) {
22730                if (displayId == DEFAULT_DISPLAY) {
22731                    // Override configuration of the default display duplicates global config, so
22732                    // we're calling global config update instead for default display. It will also
22733                    // apply the correct override config.
22734                    changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
22735                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
22736                } else {
22737                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
22738                }
22739            }
22740
22741            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22742        } finally {
22743            if (mWindowManager != null) {
22744                mWindowManager.continueSurfaceLayout();
22745            }
22746        }
22747
22748        if (result != null) {
22749            result.changes = changes;
22750            result.activityRelaunched = !kept;
22751        }
22752        return kept;
22753    }
22754
22755    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
22756            int displayId) {
22757        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
22758        final int changes = mTempConfig.updateFrom(values);
22759        if (changes != 0) {
22760            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
22761                    + mTempConfig + " for displayId=" + displayId);
22762            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
22763
22764            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
22765            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
22766                mAppWarnings.onDensityChanged();
22767
22768                killAllBackgroundProcessesExcept(N,
22769                        ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
22770            }
22771        }
22772
22773        // Update the configuration with WM first and check if any of the stacks need to be resized
22774        // due to the configuration change. If so, resize the stacks now and do any relaunches if
22775        // necessary. This way we don't need to relaunch again afterwards in
22776        // ensureActivityConfiguration().
22777        if (mWindowManager != null) {
22778            final int[] resizedStacks =
22779                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
22780            if (resizedStacks != null) {
22781                for (int stackId : resizedStacks) {
22782                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
22783                }
22784            }
22785        }
22786
22787        return changes;
22788    }
22789
22790    /** Applies latest configuration and/or visibility updates if needed. */
22791    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
22792        boolean kept = true;
22793        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
22794        // mainStack is null during startup.
22795        if (mainStack != null) {
22796            if (changes != 0 && starting == null) {
22797                // If the configuration changed, and the caller is not already
22798                // in the process of starting an activity, then find the top
22799                // activity to check if its configuration needs to change.
22800                starting = mainStack.topRunningActivityLocked();
22801            }
22802
22803            if (starting != null) {
22804                kept = starting.ensureActivityConfiguration(changes,
22805                        false /* preserveWindow */);
22806                // And we need to make sure at this point that all other activities
22807                // are made visible with the correct configuration.
22808                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
22809                        !PRESERVE_WINDOWS);
22810            }
22811        }
22812
22813        return kept;
22814    }
22815
22816    /** Helper method that requests bounds from WM and applies them to stack. */
22817    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
22818        final Rect newStackBounds = new Rect();
22819        final ActivityStack stack = mStackSupervisor.getStack(stackId);
22820
22821        // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
22822        if (stack == null) {
22823            final StringWriter writer = new StringWriter();
22824            final PrintWriter printWriter = new PrintWriter(writer);
22825            mStackSupervisor.dumpDisplays(printWriter);
22826            printWriter.flush();
22827
22828            Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
22829        }
22830
22831        stack.getBoundsForNewConfiguration(newStackBounds);
22832        mStackSupervisor.resizeStackLocked(
22833                stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
22834                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
22835                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
22836    }
22837
22838    /**
22839     * Decide based on the configuration whether we should show the ANR,
22840     * crash, etc dialogs.  The idea is that if there is no affordance to
22841     * press the on-screen buttons, or the user experience would be more
22842     * greatly impacted than the crash itself, we shouldn't show the dialog.
22843     *
22844     * A thought: SystemUI might also want to get told about this, the Power
22845     * dialog / global actions also might want different behaviors.
22846     */
22847    private void updateShouldShowDialogsLocked(Configuration config) {
22848        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
22849                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
22850                                   && config.navigation == Configuration.NAVIGATION_NONAV);
22851        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
22852        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
22853                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
22854                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
22855                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
22856        final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
22857                HIDE_ERROR_DIALOGS, 0) != 0;
22858        mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
22859    }
22860
22861    @Override
22862    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
22863        synchronized (this) {
22864            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
22865            if (srec != null) {
22866                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
22867            }
22868        }
22869        return false;
22870    }
22871
22872    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
22873            Intent resultData) {
22874
22875        synchronized (this) {
22876            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
22877            if (r != null) {
22878                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
22879            }
22880            return false;
22881        }
22882    }
22883
22884    public int getLaunchedFromUid(IBinder activityToken) {
22885        ActivityRecord srec;
22886        synchronized (this) {
22887            srec = ActivityRecord.forTokenLocked(activityToken);
22888        }
22889        if (srec == null) {
22890            return -1;
22891        }
22892        return srec.launchedFromUid;
22893    }
22894
22895    public String getLaunchedFromPackage(IBinder activityToken) {
22896        ActivityRecord srec;
22897        synchronized (this) {
22898            srec = ActivityRecord.forTokenLocked(activityToken);
22899        }
22900        if (srec == null) {
22901            return null;
22902        }
22903        return srec.launchedFromPackage;
22904    }
22905
22906    // =========================================================
22907    // LIFETIME MANAGEMENT
22908    // =========================================================
22909
22910    // Returns whether the app is receiving broadcast.
22911    // If receiving, fetch all broadcast queues which the app is
22912    // the current [or imminent] receiver on.
22913    private boolean isReceivingBroadcastLocked(ProcessRecord app,
22914            ArraySet<BroadcastQueue> receivingQueues) {
22915        final int N = app.curReceivers.size();
22916        if (N > 0) {
22917            for (int i = 0; i < N; i++) {
22918                receivingQueues.add(app.curReceivers.valueAt(i).queue);
22919            }
22920            return true;
22921        }
22922
22923        // It's not the current receiver, but it might be starting up to become one
22924        for (BroadcastQueue queue : mBroadcastQueues) {
22925            final BroadcastRecord r = queue.mPendingBroadcast;
22926            if (r != null && r.curApp == app) {
22927                // found it; report which queue it's in
22928                receivingQueues.add(queue);
22929            }
22930        }
22931
22932        return !receivingQueues.isEmpty();
22933    }
22934
22935    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
22936            int targetUid, ComponentName targetComponent, String targetProcess) {
22937        if (!mTrackingAssociations) {
22938            return null;
22939        }
22940        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22941                = mAssociations.get(targetUid);
22942        if (components == null) {
22943            components = new ArrayMap<>();
22944            mAssociations.put(targetUid, components);
22945        }
22946        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22947        if (sourceUids == null) {
22948            sourceUids = new SparseArray<>();
22949            components.put(targetComponent, sourceUids);
22950        }
22951        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22952        if (sourceProcesses == null) {
22953            sourceProcesses = new ArrayMap<>();
22954            sourceUids.put(sourceUid, sourceProcesses);
22955        }
22956        Association ass = sourceProcesses.get(sourceProcess);
22957        if (ass == null) {
22958            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
22959                    targetProcess);
22960            sourceProcesses.put(sourceProcess, ass);
22961        }
22962        ass.mCount++;
22963        ass.mNesting++;
22964        if (ass.mNesting == 1) {
22965            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
22966            ass.mLastState = sourceState;
22967        }
22968        return ass;
22969    }
22970
22971    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
22972            ComponentName targetComponent) {
22973        if (!mTrackingAssociations) {
22974            return;
22975        }
22976        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22977                = mAssociations.get(targetUid);
22978        if (components == null) {
22979            return;
22980        }
22981        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22982        if (sourceUids == null) {
22983            return;
22984        }
22985        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22986        if (sourceProcesses == null) {
22987            return;
22988        }
22989        Association ass = sourceProcesses.get(sourceProcess);
22990        if (ass == null || ass.mNesting <= 0) {
22991            return;
22992        }
22993        ass.mNesting--;
22994        if (ass.mNesting == 0) {
22995            long uptime = SystemClock.uptimeMillis();
22996            ass.mTime += uptime - ass.mStartTime;
22997            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22998                    += uptime - ass.mLastStateUptime;
22999            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
23000        }
23001    }
23002
23003    private void noteUidProcessState(final int uid, final int state) {
23004        mBatteryStatsService.noteUidProcessState(uid, state);
23005        mAppOpsService.updateUidProcState(uid, state);
23006        if (mTrackingAssociations) {
23007            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
23008                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
23009                        = mAssociations.valueAt(i1);
23010                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
23011                    SparseArray<ArrayMap<String, Association>> sourceUids
23012                            = targetComponents.valueAt(i2);
23013                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
23014                    if (sourceProcesses != null) {
23015                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
23016                            Association ass = sourceProcesses.valueAt(i4);
23017                            if (ass.mNesting >= 1) {
23018                                // currently associated
23019                                long uptime = SystemClock.uptimeMillis();
23020                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
23021                                        += uptime - ass.mLastStateUptime;
23022                                ass.mLastState = state;
23023                                ass.mLastStateUptime = uptime;
23024                            }
23025                        }
23026                    }
23027                }
23028            }
23029        }
23030    }
23031
23032    private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
23033            boolean doingAll, long now) {
23034        if (mAdjSeq == app.adjSeq) {
23035            if (app.adjSeq == app.completedAdjSeq) {
23036                // This adjustment has already been computed successfully.
23037                return false;
23038            } else {
23039                // The process is being computed, so there is a cycle. We cannot
23040                // rely on this process's state.
23041                app.containsCycle = true;
23042                return false;
23043            }
23044        }
23045
23046        if (app.thread == null) {
23047            app.adjSeq = mAdjSeq;
23048            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23049            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23050            app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ;
23051            app.completedAdjSeq = app.adjSeq;
23052            return false;
23053        }
23054
23055        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
23056        app.adjSource = null;
23057        app.adjTarget = null;
23058        app.empty = false;
23059        app.cached = false;
23060
23061        final int activitiesSize = app.activities.size();
23062        final int appUid = app.info.uid;
23063        final int logUid = mCurOomAdjUid;
23064
23065        int prevAppAdj = app.curAdj;
23066
23067        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
23068            // The max adjustment doesn't allow this app to be anything
23069            // below foreground, so it is not worth doing work for it.
23070            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23071                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making fixed: " + app);
23072            }
23073            app.adjType = "fixed";
23074            app.adjSeq = mAdjSeq;
23075            app.curRawAdj = app.maxAdj;
23076            app.foregroundActivities = false;
23077            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23078            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
23079            // System processes can do UI, and when they do we want to have
23080            // them trim their memory after the user leaves the UI.  To
23081            // facilitate this, here we need to determine whether or not it
23082            // is currently showing UI.
23083            app.systemNoUi = true;
23084            if (app == TOP_APP) {
23085                app.systemNoUi = false;
23086                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23087                app.adjType = "pers-top-activity";
23088            } else if (app.hasTopUi) {
23089                // sched group/proc state adjustment is below
23090                app.systemNoUi = false;
23091                app.adjType = "pers-top-ui";
23092            } else if (activitiesSize > 0) {
23093                for (int j = 0; j < activitiesSize; j++) {
23094                    final ActivityRecord r = app.activities.get(j);
23095                    if (r.visible) {
23096                        app.systemNoUi = false;
23097                    }
23098                }
23099            }
23100            if (!app.systemNoUi) {
23101              if (mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE) {
23102                  // screen on, promote UI
23103                  app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
23104                  app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23105              } else {
23106                  // screen off, restrict UI scheduling
23107                  app.curProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23108                  app.curSchedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
23109              }
23110            }
23111            app.curAdj = app.maxAdj;
23112            app.completedAdjSeq = app.adjSeq;
23113            // if curAdj is less than prevAppAdj, then this process was promoted
23114            return app.curAdj < prevAppAdj;
23115        }
23116
23117        app.systemNoUi = false;
23118
23119        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
23120
23121        // Determine the importance of the process, starting with most
23122        // important to least, and assign an appropriate OOM adjustment.
23123        int adj;
23124        int schedGroup;
23125        int procState;
23126        int cachedAdjSeq;
23127
23128        boolean foregroundActivities = false;
23129        mTmpBroadcastQueue.clear();
23130        if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
23131            // The last app on the list is the foreground app.
23132            adj = ProcessList.FOREGROUND_APP_ADJ;
23133            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23134            app.adjType = "top-activity";
23135            foregroundActivities = true;
23136            procState = PROCESS_STATE_CUR_TOP;
23137            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23138                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
23139            }
23140        } else if (app.runningRemoteAnimation) {
23141            adj = ProcessList.VISIBLE_APP_ADJ;
23142            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
23143            app.adjType = "running-remote-anim";
23144            procState = PROCESS_STATE_CUR_TOP;
23145            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23146                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making running remote anim: " + app);
23147            }
23148        } else if (app.instr != null) {
23149            // Don't want to kill running instrumentation.
23150            adj = ProcessList.FOREGROUND_APP_ADJ;
23151            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23152            app.adjType = "instrumentation";
23153            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
23154            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23155                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app);
23156            }
23157        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
23158            // An app that is currently receiving a broadcast also
23159            // counts as being in the foreground for OOM killer purposes.
23160            // It's placed in a sched group based on the nature of the
23161            // broadcast as reflected by which queue it's active in.
23162            adj = ProcessList.FOREGROUND_APP_ADJ;
23163            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
23164                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
23165            app.adjType = "broadcast";
23166            procState = ActivityManager.PROCESS_STATE_RECEIVER;
23167            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23168                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making broadcast: " + app);
23169            }
23170        } else if (app.executingServices.size() > 0) {
23171            // An app that is currently executing a service callback also
23172            // counts as being in the foreground.
23173            adj = ProcessList.FOREGROUND_APP_ADJ;
23174            schedGroup = app.execServicesFg ?
23175                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
23176            app.adjType = "exec-service";
23177            procState = ActivityManager.PROCESS_STATE_SERVICE;
23178            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23179                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app);
23180            }
23181            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
23182        } else if (app == TOP_APP) {
23183            adj = ProcessList.FOREGROUND_APP_ADJ;
23184            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23185            app.adjType = "top-sleeping";
23186            foregroundActivities = true;
23187            procState = PROCESS_STATE_CUR_TOP;
23188            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23189                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top (sleeping): " + app);
23190            }
23191        } else {
23192            // As far as we know the process is empty.  We may change our mind later.
23193            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23194            // At this point we don't actually know the adjustment.  Use the cached adj
23195            // value that the caller wants us to.
23196            adj = cachedAdj;
23197            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23198            app.cached = true;
23199            app.empty = true;
23200            app.adjType = "cch-empty";
23201            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23202                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making empty: " + app);
23203            }
23204        }
23205
23206        // Examine all activities if not already foreground.
23207        if (!foregroundActivities && activitiesSize > 0) {
23208            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
23209            for (int j = 0; j < activitiesSize; j++) {
23210                final ActivityRecord r = app.activities.get(j);
23211                if (r.app != app) {
23212                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
23213                            + " instead of expected " + app);
23214                    if (r.app == null || (r.app.uid == app.uid)) {
23215                        // Only fix things up when they look sane
23216                        r.setProcess(app);
23217                    } else {
23218                        continue;
23219                    }
23220                }
23221                if (r.visible) {
23222                    // App has a visible activity; only upgrade adjustment.
23223                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
23224                        adj = ProcessList.VISIBLE_APP_ADJ;
23225                        app.adjType = "vis-activity";
23226                        if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23227                            reportOomAdjMessageLocked(TAG_OOM_ADJ,
23228                                    "Raise adj to vis-activity: " + app);
23229                        }
23230                    }
23231                    if (procState > PROCESS_STATE_CUR_TOP) {
23232                        procState = PROCESS_STATE_CUR_TOP;
23233                        app.adjType = "vis-activity";
23234                        if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23235                            reportOomAdjMessageLocked(TAG_OOM_ADJ,
23236                                    "Raise procstate to vis-activity (top): " + app);
23237                        }
23238                    }
23239                    if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
23240                        schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23241                    }
23242                    app.cached = false;
23243                    app.empty = false;
23244                    foregroundActivities = true;
23245                    final TaskRecord task = r.getTask();
23246                    if (task != null && minLayer > 0) {
23247                        final int layer = task.mLayerRank;
23248                        if (layer >= 0 && minLayer > layer) {
23249                            minLayer = layer;
23250                        }
23251                    }
23252                    break;
23253                } else if (r.isState(ActivityState.PAUSING, ActivityState.PAUSED)) {
23254                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23255                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23256                        app.adjType = "pause-activity";
23257                        if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23258                            reportOomAdjMessageLocked(TAG_OOM_ADJ,
23259                                    "Raise adj to pause-activity: "  + app);
23260                        }
23261                    }
23262                    if (procState > PROCESS_STATE_CUR_TOP) {
23263                        procState = PROCESS_STATE_CUR_TOP;
23264                        app.adjType = "pause-activity";
23265                        if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23266                            reportOomAdjMessageLocked(TAG_OOM_ADJ,
23267                                    "Raise procstate to pause-activity (top): "  + app);
23268                        }
23269                    }
23270                    if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
23271                        schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23272                    }
23273                    app.cached = false;
23274                    app.empty = false;
23275                    foregroundActivities = true;
23276                } else if (r.isState(ActivityState.STOPPING)) {
23277                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23278                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23279                        app.adjType = "stop-activity";
23280                        if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23281                            reportOomAdjMessageLocked(TAG_OOM_ADJ,
23282                                    "Raise adj to stop-activity: "  + app);
23283                        }
23284                    }
23285                    // For the process state, we will at this point consider the
23286                    // process to be cached.  It will be cached either as an activity
23287                    // or empty depending on whether the activity is finishing.  We do
23288                    // this so that we can treat the process as cached for purposes of
23289                    // memory trimming (determing current memory level, trim command to
23290                    // send to process) since there can be an arbitrary number of stopping
23291                    // processes and they should soon all go into the cached state.
23292                    if (!r.finishing) {
23293                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23294                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23295                            app.adjType = "stop-activity";
23296                            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23297                                reportOomAdjMessageLocked(TAG_OOM_ADJ,
23298                                        "Raise procstate to stop-activity: " + app);
23299                            }
23300                        }
23301                    }
23302                    app.cached = false;
23303                    app.empty = false;
23304                    foregroundActivities = true;
23305                } else {
23306                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23307                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
23308                        app.adjType = "cch-act";
23309                        if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23310                            reportOomAdjMessageLocked(TAG_OOM_ADJ,
23311                                    "Raise procstate to cached activity: " + app);
23312                        }
23313                    }
23314                }
23315            }
23316            if (adj == ProcessList.VISIBLE_APP_ADJ) {
23317                adj += minLayer;
23318            }
23319        }
23320        if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) {
23321            procState = ActivityManager.PROCESS_STATE_CACHED_RECENT;
23322            app.adjType = "cch-rec";
23323            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23324                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to cached recent: " + app);
23325            }
23326        }
23327
23328        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
23329                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
23330            if (app.foregroundServices) {
23331                // The user is aware of this app, so make it visible.
23332                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23333                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
23334                app.cached = false;
23335                app.adjType = "fg-service";
23336                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23337                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23338                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to fg service: " + app);
23339                }
23340            } else if (app.hasOverlayUi) {
23341                // The process is display an overlay UI.
23342                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23343                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23344                app.cached = false;
23345                app.adjType = "has-overlay-ui";
23346                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23347                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23348                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to overlay ui: " + app);
23349                }
23350            }
23351        }
23352
23353        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
23354                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23355            if (app.forcingToImportant != null) {
23356                // This is currently used for toasts...  they are not interactive, and
23357                // we don't want them to cause the app to become fully foreground (and
23358                // thus out of background check), so we yes the best background level we can.
23359                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
23360                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23361                app.cached = false;
23362                app.adjType = "force-imp";
23363                app.adjSource = app.forcingToImportant;
23364                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23365                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23366                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to force imp: " + app);
23367                }
23368            }
23369        }
23370
23371        if (app == mHeavyWeightProcess) {
23372            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
23373                // We don't want to kill the current heavy-weight process.
23374                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
23375                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23376                app.cached = false;
23377                app.adjType = "heavy";
23378                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23379                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to heavy: " + app);
23380                }
23381            }
23382            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
23383                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
23384                app.adjType = "heavy";
23385                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23386                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to heavy: " + app);
23387                }
23388            }
23389        }
23390
23391        if (app == mHomeProcess) {
23392            if (adj > ProcessList.HOME_APP_ADJ) {
23393                // This process is hosting what we currently consider to be the
23394                // home app, so we don't want to let it go into the background.
23395                adj = ProcessList.HOME_APP_ADJ;
23396                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23397                app.cached = false;
23398                app.adjType = "home";
23399                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23400                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to home: " + app);
23401                }
23402            }
23403            if (procState > ActivityManager.PROCESS_STATE_HOME) {
23404                procState = ActivityManager.PROCESS_STATE_HOME;
23405                app.adjType = "home";
23406                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23407                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to home: " + app);
23408                }
23409            }
23410        }
23411
23412        if (app == mPreviousProcess && app.activities.size() > 0) {
23413            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23414                // This was the previous process that showed UI to the user.
23415                // We want to try to keep it around more aggressively, to give
23416                // a good experience around switching between two apps.
23417                adj = ProcessList.PREVIOUS_APP_ADJ;
23418                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23419                app.cached = false;
23420                app.adjType = "previous";
23421                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23422                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to prev: " + app);
23423                }
23424            }
23425            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23426                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23427                app.adjType = "previous";
23428                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23429                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to prev: " + app);
23430                }
23431            }
23432        }
23433
23434        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
23435                + " reason=" + app.adjType);
23436
23437        // By default, we use the computed adjustment.  It may be changed if
23438        // there are applications dependent on our services or providers, but
23439        // this gives us a baseline and makes sure we don't get into an
23440        // infinite recursion.
23441        app.curRawAdj = adj;
23442        app.hasStartedServices = false;
23443        app.adjSeq = mAdjSeq;
23444
23445        if (mBackupTarget != null && app == mBackupTarget.app) {
23446            // If possible we want to avoid killing apps while they're being backed up
23447            if (adj > ProcessList.BACKUP_APP_ADJ) {
23448                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
23449                adj = ProcessList.BACKUP_APP_ADJ;
23450                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23451                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23452                }
23453                app.adjType = "backup";
23454                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23455                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to backup: " + app);
23456                }
23457                app.cached = false;
23458            }
23459            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
23460                procState = ActivityManager.PROCESS_STATE_BACKUP;
23461                app.adjType = "backup";
23462                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23463                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to backup: " + app);
23464                }
23465            }
23466        }
23467
23468        boolean mayBeTop = false;
23469        String mayBeTopType = null;
23470        Object mayBeTopSource = null;
23471        Object mayBeTopTarget = null;
23472
23473        for (int is = app.services.size()-1;
23474                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23475                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23476                        || procState > ActivityManager.PROCESS_STATE_TOP);
23477                is--) {
23478            ServiceRecord s = app.services.valueAt(is);
23479            if (s.startRequested) {
23480                app.hasStartedServices = true;
23481                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
23482                    procState = ActivityManager.PROCESS_STATE_SERVICE;
23483                    app.adjType = "started-services";
23484                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23485                        reportOomAdjMessageLocked(TAG_OOM_ADJ,
23486                                "Raise procstate to started service: " + app);
23487                    }
23488                }
23489                if (app.hasShownUi && app != mHomeProcess) {
23490                    // If this process has shown some UI, let it immediately
23491                    // go to the LRU list because it may be pretty heavy with
23492                    // UI stuff.  We'll tag it with a label just to help
23493                    // debug and understand what is going on.
23494                    if (adj > ProcessList.SERVICE_ADJ) {
23495                        app.adjType = "cch-started-ui-services";
23496                    }
23497                } else {
23498                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23499                        // This service has seen some activity within
23500                        // recent memory, so we will keep its process ahead
23501                        // of the background processes.
23502                        if (adj > ProcessList.SERVICE_ADJ) {
23503                            adj = ProcessList.SERVICE_ADJ;
23504                            app.adjType = "started-services";
23505                            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23506                                reportOomAdjMessageLocked(TAG_OOM_ADJ,
23507                                        "Raise adj to started service: " + app);
23508                            }
23509                            app.cached = false;
23510                        }
23511                    }
23512                    // If we have let the service slide into the background
23513                    // state, still have some text describing what it is doing
23514                    // even though the service no longer has an impact.
23515                    if (adj > ProcessList.SERVICE_ADJ) {
23516                        app.adjType = "cch-started-services";
23517                    }
23518                }
23519            }
23520
23521            for (int conni = s.connections.size()-1;
23522                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23523                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23524                            || procState > ActivityManager.PROCESS_STATE_TOP);
23525                    conni--) {
23526                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
23527                for (int i = 0;
23528                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
23529                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23530                                || procState > ActivityManager.PROCESS_STATE_TOP);
23531                        i++) {
23532                    // XXX should compute this based on the max of
23533                    // all connected clients.
23534                    ConnectionRecord cr = clist.get(i);
23535                    if (cr.binding.client == app) {
23536                        // Binding to ourself is not interesting.
23537                        continue;
23538                    }
23539
23540                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
23541                        ProcessRecord client = cr.binding.client;
23542                        computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
23543                        if (client.containsCycle) {
23544                            // We've detected a cycle. We should ignore this connection and allow
23545                            // this process to retry computeOomAdjLocked later in case a later-checked
23546                            // connection from a client  would raise its priority legitimately.
23547                            app.containsCycle = true;
23548                            continue;
23549                        }
23550                        int clientAdj = client.curRawAdj;
23551                        int clientProcState = client.curProcState;
23552                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23553                            // If the other app is cached for any reason, for purposes here
23554                            // we are going to consider it empty.  The specific cached state
23555                            // doesn't propagate except under certain conditions.
23556                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23557                        }
23558                        String adjType = null;
23559                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
23560                            // Not doing bind OOM management, so treat
23561                            // this guy more like a started service.
23562                            if (app.hasShownUi && app != mHomeProcess) {
23563                                // If this process has shown some UI, let it immediately
23564                                // go to the LRU list because it may be pretty heavy with
23565                                // UI stuff.  We'll tag it with a label just to help
23566                                // debug and understand what is going on.
23567                                if (adj > clientAdj) {
23568                                    adjType = "cch-bound-ui-services";
23569                                }
23570                                app.cached = false;
23571                                clientAdj = adj;
23572                                clientProcState = procState;
23573                            } else {
23574                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23575                                    // This service has not seen activity within
23576                                    // recent memory, so allow it to drop to the
23577                                    // LRU list if there is no other reason to keep
23578                                    // it around.  We'll also tag it with a label just
23579                                    // to help debug and undertand what is going on.
23580                                    if (adj > clientAdj) {
23581                                        adjType = "cch-bound-services";
23582                                    }
23583                                    clientAdj = adj;
23584                                }
23585                            }
23586                        }
23587                        if (adj > clientAdj) {
23588                            // If this process has recently shown UI, and
23589                            // the process that is binding to it is less
23590                            // important than being visible, then we don't
23591                            // care about the binding as much as we care
23592                            // about letting this process get into the LRU
23593                            // list to be killed and restarted if needed for
23594                            // memory.
23595                            if (app.hasShownUi && app != mHomeProcess
23596                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23597                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
23598                                    adjType = "cch-bound-ui-services";
23599                                }
23600                            } else {
23601                                int newAdj;
23602                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
23603                                        |Context.BIND_IMPORTANT)) != 0) {
23604                                    if (clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
23605                                        newAdj = clientAdj;
23606                                    } else {
23607                                        // make this service persistent
23608                                        newAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
23609                                        schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23610                                        procState = ActivityManager.PROCESS_STATE_PERSISTENT;
23611                                    }
23612                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
23613                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
23614                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23615                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
23616                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
23617                                    newAdj = clientAdj;
23618                                } else {
23619                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
23620                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
23621                                    } else {
23622                                        newAdj = adj;
23623                                    }
23624                                }
23625                                if (!client.cached) {
23626                                    app.cached = false;
23627                                }
23628                                if (adj >  newAdj) {
23629                                    adj = newAdj;
23630                                    adjType = "service";
23631                                }
23632                            }
23633                        }
23634                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
23635                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
23636                            // This will treat important bound services identically to
23637                            // the top app, which may behave differently than generic
23638                            // foreground work.
23639                            if (client.curSchedGroup > schedGroup) {
23640                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23641                                    schedGroup = client.curSchedGroup;
23642                                } else {
23643                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23644                                }
23645                            }
23646                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23647                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23648                                    // Special handling of clients who are in the top state.
23649                                    // We *may* want to consider this process to be in the
23650                                    // top state as well, but only if there is not another
23651                                    // reason for it to be running.  Being on the top is a
23652                                    // special state, meaning you are specifically running
23653                                    // for the current top app.  If the process is already
23654                                    // running in the background for some other reason, it
23655                                    // is more important to continue considering it to be
23656                                    // in the background state.
23657                                    mayBeTop = true;
23658                                    mayBeTopType = "service";
23659                                    mayBeTopSource = cr.binding.client;
23660                                    mayBeTopTarget = s.name;
23661                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23662                                } else {
23663                                    // Special handling for above-top states (persistent
23664                                    // processes).  These should not bring the current process
23665                                    // into the top state, since they are not on top.  Instead
23666                                    // give them the best state after that.
23667                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
23668                                        clientProcState =
23669                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23670                                    } else if (mWakefulness
23671                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
23672                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
23673                                                    != 0) {
23674                                        clientProcState =
23675                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23676                                    } else {
23677                                        clientProcState =
23678                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23679                                    }
23680                                }
23681                            }
23682                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
23683                            if (clientProcState <
23684                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23685                                clientProcState =
23686                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23687                            }
23688                        } else {
23689                            if (clientProcState <
23690                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
23691                                clientProcState =
23692                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
23693                            }
23694                        }
23695                        if (procState > clientProcState) {
23696                            procState = clientProcState;
23697                            if (adjType == null) {
23698                                adjType = "service";
23699                            }
23700                        }
23701                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
23702                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
23703                            app.pendingUiClean = true;
23704                        }
23705                        if (adjType != null) {
23706                            app.adjType = adjType;
23707                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23708                                    .REASON_SERVICE_IN_USE;
23709                            app.adjSource = cr.binding.client;
23710                            app.adjSourceProcState = clientProcState;
23711                            app.adjTarget = s.name;
23712                            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23713                                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
23714                                        + ": " + app + ", due to " + cr.binding.client
23715                                        + " adj=" + adj + " procState="
23716                                        + ProcessList.makeProcStateString(procState));
23717                            }
23718                        }
23719                    }
23720                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
23721                        app.treatLikeActivity = true;
23722                    }
23723                    final ActivityRecord a = cr.activity;
23724                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
23725                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && (a.visible
23726                                || a.isState(ActivityState.RESUMED, ActivityState.PAUSING))) {
23727                            adj = ProcessList.FOREGROUND_APP_ADJ;
23728                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
23729                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23730                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
23731                                } else {
23732                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23733                                }
23734                            }
23735                            app.cached = false;
23736                            app.adjType = "service";
23737                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23738                                    .REASON_SERVICE_IN_USE;
23739                            app.adjSource = a;
23740                            app.adjSourceProcState = procState;
23741                            app.adjTarget = s.name;
23742                            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23743                                reportOomAdjMessageLocked(TAG_OOM_ADJ,
23744                                        "Raise to service w/activity: " + app);
23745                            }
23746                        }
23747                    }
23748                }
23749            }
23750        }
23751
23752        for (int provi = app.pubProviders.size()-1;
23753                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23754                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23755                        || procState > ActivityManager.PROCESS_STATE_TOP);
23756                provi--) {
23757            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
23758            for (int i = cpr.connections.size()-1;
23759                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23760                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23761                            || procState > ActivityManager.PROCESS_STATE_TOP);
23762                    i--) {
23763                ContentProviderConnection conn = cpr.connections.get(i);
23764                ProcessRecord client = conn.client;
23765                if (client == app) {
23766                    // Being our own client is not interesting.
23767                    continue;
23768                }
23769                computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
23770                if (client.containsCycle) {
23771                    // We've detected a cycle. We should ignore this connection and allow
23772                    // this process to retry computeOomAdjLocked later in case a later-checked
23773                    // connection from a client  would raise its priority legitimately.
23774                    app.containsCycle = true;
23775                    continue;
23776                }
23777                int clientAdj = client.curRawAdj;
23778                int clientProcState = client.curProcState;
23779                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23780                    // If the other app is cached for any reason, for purposes here
23781                    // we are going to consider it empty.
23782                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23783                }
23784                String adjType = null;
23785                if (adj > clientAdj) {
23786                    if (app.hasShownUi && app != mHomeProcess
23787                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23788                        adjType = "cch-ui-provider";
23789                    } else {
23790                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
23791                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
23792                        adjType = "provider";
23793                    }
23794                    app.cached &= client.cached;
23795                }
23796                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23797                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23798                        // Special handling of clients who are in the top state.
23799                        // We *may* want to consider this process to be in the
23800                        // top state as well, but only if there is not another
23801                        // reason for it to be running.  Being on the top is a
23802                        // special state, meaning you are specifically running
23803                        // for the current top app.  If the process is already
23804                        // running in the background for some other reason, it
23805                        // is more important to continue considering it to be
23806                        // in the background state.
23807                        mayBeTop = true;
23808                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23809                        mayBeTopType = adjType = "provider-top";
23810                        mayBeTopSource = client;
23811                        mayBeTopTarget = cpr.name;
23812                    } else {
23813                        // Special handling for above-top states (persistent
23814                        // processes).  These should not bring the current process
23815                        // into the top state, since they are not on top.  Instead
23816                        // give them the best state after that.
23817                        clientProcState =
23818                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23819                        if (adjType == null) {
23820                            adjType = "provider";
23821                        }
23822                    }
23823                }
23824                if (procState > clientProcState) {
23825                    procState = clientProcState;
23826                }
23827                if (client.curSchedGroup > schedGroup) {
23828                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23829                }
23830                if (adjType != null) {
23831                    app.adjType = adjType;
23832                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23833                            .REASON_PROVIDER_IN_USE;
23834                    app.adjSource = client;
23835                    app.adjSourceProcState = clientProcState;
23836                    app.adjTarget = cpr.name;
23837                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23838                        reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType
23839                                + ": " + app + ", due to " + client
23840                                + " adj=" + adj + " procState="
23841                                + ProcessList.makeProcStateString(procState));
23842                    }
23843                }
23844            }
23845            // If the provider has external (non-framework) process
23846            // dependencies, ensure that its adjustment is at least
23847            // FOREGROUND_APP_ADJ.
23848            if (cpr.hasExternalProcessHandles()) {
23849                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
23850                    adj = ProcessList.FOREGROUND_APP_ADJ;
23851                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23852                    app.cached = false;
23853                    app.adjType = "ext-provider";
23854                    app.adjTarget = cpr.name;
23855                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23856                        reportOomAdjMessageLocked(TAG_OOM_ADJ,
23857                                "Raise adj to external provider: " + app);
23858                    }
23859                }
23860                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23861                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23862                    reportOomAdjMessageLocked(TAG_OOM_ADJ,
23863                            "Raise procstate to external provider: " + app);
23864                }
23865            }
23866        }
23867
23868        if (app.lastProviderTime > 0 &&
23869                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
23870            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23871                adj = ProcessList.PREVIOUS_APP_ADJ;
23872                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23873                app.cached = false;
23874                app.adjType = "recent-provider";
23875                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23876                    reportOomAdjMessageLocked(TAG_OOM_ADJ,
23877                            "Raise adj to recent provider: " + app);
23878                }
23879            }
23880            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23881                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23882                app.adjType = "recent-provider";
23883                if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23884                    reportOomAdjMessageLocked(TAG_OOM_ADJ,
23885                            "Raise procstate to recent provider: " + app);
23886                }
23887            }
23888        }
23889
23890        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
23891            // A client of one of our services or providers is in the top state.  We
23892            // *may* want to be in the top state, but not if we are already running in
23893            // the background for some other reason.  For the decision here, we are going
23894            // to pick out a few specific states that we want to remain in when a client
23895            // is top (states that tend to be longer-term) and otherwise allow it to go
23896            // to the top state.
23897            switch (procState) {
23898                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
23899                case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
23900                    // Something else is keeping it at this level, just leave it.
23901                    break;
23902                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
23903                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
23904                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
23905                case ActivityManager.PROCESS_STATE_SERVICE:
23906                    // These all are longer-term states, so pull them up to the top
23907                    // of the background states, but not all the way to the top state.
23908                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23909                    app.adjType = mayBeTopType;
23910                    app.adjSource = mayBeTopSource;
23911                    app.adjTarget = mayBeTopTarget;
23912                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23913                        reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
23914                                + ": " + app + ", due to " + mayBeTopSource
23915                                + " adj=" + adj + " procState="
23916                                + ProcessList.makeProcStateString(procState));
23917                    }
23918                    break;
23919                default:
23920                    // Otherwise, top is a better choice, so take it.
23921                    procState = ActivityManager.PROCESS_STATE_TOP;
23922                    app.adjType = mayBeTopType;
23923                    app.adjSource = mayBeTopSource;
23924                    app.adjTarget = mayBeTopTarget;
23925                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
23926                        reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
23927                                + ": " + app + ", due to " + mayBeTopSource
23928                                + " adj=" + adj + " procState="
23929                                + ProcessList.makeProcStateString(procState));
23930                    }
23931                    break;
23932            }
23933        }
23934
23935        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
23936            if (app.hasClientActivities) {
23937                // This is a cached process, but with client activities.  Mark it so.
23938                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
23939                app.adjType = "cch-client-act";
23940            } else if (app.treatLikeActivity) {
23941                // This is a cached process, but somebody wants us to treat it like it has
23942                // an activity, okay!
23943                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
23944                app.adjType = "cch-as-act";
23945            }
23946        }
23947
23948        if (adj == ProcessList.SERVICE_ADJ) {
23949            if (doingAll) {
23950                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
23951                mNewNumServiceProcs++;
23952                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
23953                if (!app.serviceb) {
23954                    // This service isn't far enough down on the LRU list to
23955                    // normally be a B service, but if we are low on RAM and it
23956                    // is large we want to force it down since we would prefer to
23957                    // keep launcher over it.
23958                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
23959                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
23960                        app.serviceHighRam = true;
23961                        app.serviceb = true;
23962                        //Slog.i(TAG, "ADJ " + app + " high ram!");
23963                    } else {
23964                        mNewNumAServiceProcs++;
23965                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
23966                    }
23967                } else {
23968                    app.serviceHighRam = false;
23969                }
23970            }
23971            if (app.serviceb) {
23972                adj = ProcessList.SERVICE_B_ADJ;
23973            }
23974        }
23975
23976        app.curRawAdj = adj;
23977
23978        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
23979        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
23980        if (adj > app.maxAdj) {
23981            adj = app.maxAdj;
23982            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
23983                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23984            }
23985        }
23986
23987        // Put bound foreground services in a special sched group for additional
23988        // restrictions on screen off
23989        if (procState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE &&
23990            mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) {
23991            if (schedGroup > ProcessList.SCHED_GROUP_RESTRICTED) {
23992                schedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
23993            }
23994        }
23995
23996        // Do final modification to adj.  Everything we do between here and applying
23997        // the final setAdj must be done in this function, because we will also use
23998        // it when computing the final cached adj later.  Note that we don't need to
23999        // worry about this for max adj above, since max adj will always be used to
24000        // keep it out of the cached vaues.
24001        app.curAdj = app.modifyRawOomAdj(adj);
24002        app.curSchedGroup = schedGroup;
24003        app.curProcState = procState;
24004        app.foregroundActivities = foregroundActivities;
24005        app.completedAdjSeq = mAdjSeq;
24006
24007        // if curAdj is less than prevAppAdj, then this process was promoted
24008        return app.curAdj < prevAppAdj;
24009    }
24010
24011    /**
24012     * Record new PSS sample for a process.
24013     */
24014    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
24015            long rss, int statType, long pssDuration, long now) {
24016        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
24017                swapPss * 1024, rss * 1024, statType, procState, pssDuration);
24018        proc.lastPssTime = now;
24019        proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList);
24020        if (DEBUG_PSS) Slog.d(TAG_PSS,
24021                "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
24022                + " state=" + ProcessList.makeProcStateString(procState));
24023        if (proc.initialIdlePss == 0) {
24024            proc.initialIdlePss = pss;
24025        }
24026        proc.lastPss = pss;
24027        proc.lastSwapPss = swapPss;
24028        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
24029            proc.lastCachedPss = pss;
24030            proc.lastCachedSwapPss = swapPss;
24031        }
24032
24033        final SparseArray<Pair<Long, String>> watchUids
24034                = mMemWatchProcesses.getMap().get(proc.processName);
24035        Long check = null;
24036        if (watchUids != null) {
24037            Pair<Long, String> val = watchUids.get(proc.uid);
24038            if (val == null) {
24039                val = watchUids.get(0);
24040            }
24041            if (val != null) {
24042                check = val.first;
24043            }
24044        }
24045        if (check != null) {
24046            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
24047                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24048                if (!isDebuggable) {
24049                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
24050                        isDebuggable = true;
24051                    }
24052                }
24053                if (isDebuggable) {
24054                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
24055                    final ProcessRecord myProc = proc;
24056                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
24057                    mMemWatchDumpProcName = proc.processName;
24058                    mMemWatchDumpFile = heapdumpFile.toString();
24059                    mMemWatchDumpPid = proc.pid;
24060                    mMemWatchDumpUid = proc.uid;
24061                    BackgroundThread.getHandler().post(new Runnable() {
24062                        @Override
24063                        public void run() {
24064                            revokeUriPermission(ActivityThread.currentActivityThread()
24065                                            .getApplicationThread(),
24066                                    null, DumpHeapActivity.JAVA_URI,
24067                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
24068                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
24069                                    UserHandle.myUserId());
24070                            ParcelFileDescriptor fd = null;
24071                            try {
24072                                heapdumpFile.delete();
24073                                fd = ParcelFileDescriptor.open(heapdumpFile,
24074                                        ParcelFileDescriptor.MODE_CREATE |
24075                                                ParcelFileDescriptor.MODE_TRUNCATE |
24076                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
24077                                                ParcelFileDescriptor.MODE_APPEND);
24078                                IApplicationThread thread = myProc.thread;
24079                                if (thread != null) {
24080                                    try {
24081                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
24082                                                "Requesting dump heap from "
24083                                                + myProc + " to " + heapdumpFile);
24084                                        thread.dumpHeap(/* managed= */ true,
24085                                                /* mallocInfo= */ false, /* runGc= */ false,
24086                                                heapdumpFile.toString(), fd);
24087                                    } catch (RemoteException e) {
24088                                    }
24089                                }
24090                            } catch (FileNotFoundException e) {
24091                                e.printStackTrace();
24092                            } finally {
24093                                if (fd != null) {
24094                                    try {
24095                                        fd.close();
24096                                    } catch (IOException e) {
24097                                    }
24098                                }
24099                            }
24100                        }
24101                    });
24102                } else {
24103                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
24104                            + ", but debugging not enabled");
24105                }
24106            }
24107        }
24108    }
24109
24110    /**
24111     * Schedule PSS collection of a process.
24112     */
24113    boolean requestPssLocked(ProcessRecord proc, int procState) {
24114        if (mPendingPssProcesses.contains(proc)) {
24115            return false;
24116        }
24117        if (mPendingPssProcesses.size() == 0) {
24118            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
24119        }
24120        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
24121        proc.pssProcState = procState;
24122        proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE;
24123        mPendingPssProcesses.add(proc);
24124        return true;
24125    }
24126
24127    /**
24128     * Schedule PSS collection of all processes.
24129     */
24130    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
24131        if (!always) {
24132            if (now < (mLastFullPssTime +
24133                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
24134                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
24135                return;
24136            }
24137        }
24138        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs!  memLowered=" + memLowered);
24139        mLastFullPssTime = now;
24140        mFullPssPending = true;
24141        for (int i = mPendingPssProcesses.size() - 1; i >= 0; i--) {
24142            ProcessList.abortNextPssTime(mPendingPssProcesses.get(i).procStateMemTracker);;
24143        }
24144        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
24145        mPendingPssProcesses.clear();
24146        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24147            ProcessRecord app = mLruProcesses.get(i);
24148            if (app.thread == null
24149                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
24150                continue;
24151            }
24152            if (memLowered || (always && now >
24153                            app.lastStateTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
24154                    || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
24155                app.pssProcState = app.setProcState;
24156                app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
24157                        : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
24158                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24159                        app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24160                mPendingPssProcesses.add(app);
24161            }
24162        }
24163        if (!mBgHandler.hasMessages(COLLECT_PSS_BG_MSG)) {
24164            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
24165        }
24166    }
24167
24168    public void setTestPssMode(boolean enabled) {
24169        synchronized (this) {
24170            mTestPssMode = enabled;
24171            if (enabled) {
24172                // Whenever we enable the mode, we want to take a snapshot all of current
24173                // process mem use.
24174                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
24175            }
24176        }
24177    }
24178
24179    /**
24180     * Ask a given process to GC right now.
24181     */
24182    final void performAppGcLocked(ProcessRecord app) {
24183        try {
24184            app.lastRequestedGc = SystemClock.uptimeMillis();
24185            if (app.thread != null) {
24186                if (app.reportLowMemory) {
24187                    app.reportLowMemory = false;
24188                    app.thread.scheduleLowMemory();
24189                } else {
24190                    app.thread.processInBackground();
24191                }
24192            }
24193        } catch (Exception e) {
24194            // whatever.
24195        }
24196    }
24197
24198    /**
24199     * Returns true if things are idle enough to perform GCs.
24200     */
24201    private final boolean canGcNowLocked() {
24202        boolean processingBroadcasts = false;
24203        for (BroadcastQueue q : mBroadcastQueues) {
24204            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
24205                processingBroadcasts = true;
24206            }
24207        }
24208        return !processingBroadcasts
24209                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
24210    }
24211
24212    /**
24213     * Perform GCs on all processes that are waiting for it, but only
24214     * if things are idle.
24215     */
24216    final void performAppGcsLocked() {
24217        final int N = mProcessesToGc.size();
24218        if (N <= 0) {
24219            return;
24220        }
24221        if (canGcNowLocked()) {
24222            while (mProcessesToGc.size() > 0) {
24223                ProcessRecord proc = mProcessesToGc.remove(0);
24224                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
24225                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
24226                            <= SystemClock.uptimeMillis()) {
24227                        // To avoid spamming the system, we will GC processes one
24228                        // at a time, waiting a few seconds between each.
24229                        performAppGcLocked(proc);
24230                        scheduleAppGcsLocked();
24231                        return;
24232                    } else {
24233                        // It hasn't been long enough since we last GCed this
24234                        // process...  put it in the list to wait for its time.
24235                        addProcessToGcListLocked(proc);
24236                        break;
24237                    }
24238                }
24239            }
24240
24241            scheduleAppGcsLocked();
24242        }
24243    }
24244
24245    /**
24246     * If all looks good, perform GCs on all processes waiting for them.
24247     */
24248    final void performAppGcsIfAppropriateLocked() {
24249        if (canGcNowLocked()) {
24250            performAppGcsLocked();
24251            return;
24252        }
24253        // Still not idle, wait some more.
24254        scheduleAppGcsLocked();
24255    }
24256
24257    /**
24258     * Schedule the execution of all pending app GCs.
24259     */
24260    final void scheduleAppGcsLocked() {
24261        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
24262
24263        if (mProcessesToGc.size() > 0) {
24264            // Schedule a GC for the time to the next process.
24265            ProcessRecord proc = mProcessesToGc.get(0);
24266            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
24267
24268            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
24269            long now = SystemClock.uptimeMillis();
24270            if (when < (now+mConstants.GC_TIMEOUT)) {
24271                when = now + mConstants.GC_TIMEOUT;
24272            }
24273            mHandler.sendMessageAtTime(msg, when);
24274        }
24275    }
24276
24277    /**
24278     * Add a process to the array of processes waiting to be GCed.  Keeps the
24279     * list in sorted order by the last GC time.  The process can't already be
24280     * on the list.
24281     */
24282    final void addProcessToGcListLocked(ProcessRecord proc) {
24283        boolean added = false;
24284        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
24285            if (mProcessesToGc.get(i).lastRequestedGc <
24286                    proc.lastRequestedGc) {
24287                added = true;
24288                mProcessesToGc.add(i+1, proc);
24289                break;
24290            }
24291        }
24292        if (!added) {
24293            mProcessesToGc.add(0, proc);
24294        }
24295    }
24296
24297    /**
24298     * Set up to ask a process to GC itself.  This will either do it
24299     * immediately, or put it on the list of processes to gc the next
24300     * time things are idle.
24301     */
24302    final void scheduleAppGcLocked(ProcessRecord app) {
24303        long now = SystemClock.uptimeMillis();
24304        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
24305            return;
24306        }
24307        if (!mProcessesToGc.contains(app)) {
24308            addProcessToGcListLocked(app);
24309            scheduleAppGcsLocked();
24310        }
24311    }
24312
24313    final void checkExcessivePowerUsageLocked() {
24314        updateCpuStatsNow();
24315
24316        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
24317        boolean doCpuKills = true;
24318        if (mLastPowerCheckUptime == 0) {
24319            doCpuKills = false;
24320        }
24321        final long curUptime = SystemClock.uptimeMillis();
24322        final long uptimeSince = curUptime - mLastPowerCheckUptime;
24323        mLastPowerCheckUptime = curUptime;
24324        int i = mLruProcesses.size();
24325        while (i > 0) {
24326            i--;
24327            ProcessRecord app = mLruProcesses.get(i);
24328            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24329                if (app.lastCpuTime <= 0) {
24330                    continue;
24331                }
24332                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
24333                if (DEBUG_POWER) {
24334                    StringBuilder sb = new StringBuilder(128);
24335                    sb.append("CPU for ");
24336                    app.toShortString(sb);
24337                    sb.append(": over ");
24338                    TimeUtils.formatDuration(uptimeSince, sb);
24339                    sb.append(" used ");
24340                    TimeUtils.formatDuration(cputimeUsed, sb);
24341                    sb.append(" (");
24342                    sb.append((cputimeUsed*100)/uptimeSince);
24343                    sb.append("%)");
24344                    Slog.i(TAG_POWER, sb.toString());
24345                }
24346                // If the process has used too much CPU over the last duration, the
24347                // user probably doesn't want this, so kill!
24348                if (doCpuKills && uptimeSince > 0) {
24349                    // What is the limit for this process?
24350                    int cpuLimit;
24351                    long checkDur = curUptime - app.whenUnimportant;
24352                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
24353                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
24354                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
24355                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
24356                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
24357                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
24358                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
24359                    } else {
24360                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
24361                    }
24362                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
24363                        synchronized (stats) {
24364                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
24365                                    uptimeSince, cputimeUsed);
24366                        }
24367                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
24368                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
24369                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
24370                    }
24371                }
24372                app.lastCpuTime = app.curCpuTime;
24373            }
24374        }
24375    }
24376
24377    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
24378            long nowElapsed) {
24379        boolean success = true;
24380
24381        if (app.curRawAdj != app.setRawAdj) {
24382            app.setRawAdj = app.curRawAdj;
24383        }
24384
24385        int changes = 0;
24386
24387        if (app.curAdj != app.setAdj) {
24388            ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
24389            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
24390                String msg = "Set " + app.pid + " " + app.processName + " adj "
24391                        + app.curAdj + ": " + app.adjType;
24392                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24393            }
24394            app.setAdj = app.curAdj;
24395            app.verifiedAdj = ProcessList.INVALID_ADJ;
24396        }
24397
24398        if (app.setSchedGroup != app.curSchedGroup) {
24399            int oldSchedGroup = app.setSchedGroup;
24400            app.setSchedGroup = app.curSchedGroup;
24401            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
24402                String msg = "Setting sched group of " + app.processName
24403                        + " to " + app.curSchedGroup + ": " + app.adjType;
24404                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24405            }
24406            if (app.waitingToKill != null && app.curReceivers.isEmpty()
24407                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
24408                app.kill(app.waitingToKill, true);
24409                success = false;
24410            } else {
24411                int processGroup;
24412                switch (app.curSchedGroup) {
24413                    case ProcessList.SCHED_GROUP_BACKGROUND:
24414                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
24415                        break;
24416                    case ProcessList.SCHED_GROUP_TOP_APP:
24417                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
24418                        processGroup = THREAD_GROUP_TOP_APP;
24419                        break;
24420                    case ProcessList.SCHED_GROUP_RESTRICTED:
24421                        processGroup = THREAD_GROUP_RESTRICTED;
24422                        break;
24423                    default:
24424                        processGroup = THREAD_GROUP_DEFAULT;
24425                        break;
24426                }
24427                long oldId = Binder.clearCallingIdentity();
24428                try {
24429                    setProcessGroup(app.pid, processGroup);
24430                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
24431                        // do nothing if we already switched to RT
24432                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
24433                            mVrController.onTopProcChangedLocked(app);
24434                            if (mUseFifoUiScheduling) {
24435                                // Switch UI pipeline for app to SCHED_FIFO
24436                                app.savedPriority = Process.getThreadPriority(app.pid);
24437                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
24438                                if (app.renderThreadTid != 0) {
24439                                    scheduleAsFifoPriority(app.renderThreadTid,
24440                                        /* suppressLogs */true);
24441                                    if (DEBUG_OOM_ADJ) {
24442                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
24443                                            app.renderThreadTid + ") to FIFO");
24444                                    }
24445                                } else {
24446                                    if (DEBUG_OOM_ADJ) {
24447                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
24448                                    }
24449                                }
24450                            } else {
24451                                // Boost priority for top app UI and render threads
24452                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
24453                                if (app.renderThreadTid != 0) {
24454                                    try {
24455                                        setThreadPriority(app.renderThreadTid,
24456                                                TOP_APP_PRIORITY_BOOST);
24457                                    } catch (IllegalArgumentException e) {
24458                                        // thread died, ignore
24459                                    }
24460                                }
24461                            }
24462                        }
24463                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
24464                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
24465                        mVrController.onTopProcChangedLocked(app);
24466                        if (mUseFifoUiScheduling) {
24467                            try {
24468                                // Reset UI pipeline to SCHED_OTHER
24469                                setThreadScheduler(app.pid, SCHED_OTHER, 0);
24470                                setThreadPriority(app.pid, app.savedPriority);
24471                                if (app.renderThreadTid != 0) {
24472                                    setThreadScheduler(app.renderThreadTid,
24473                                        SCHED_OTHER, 0);
24474                                    setThreadPriority(app.renderThreadTid, -4);
24475                                }
24476                            } catch (IllegalArgumentException e) {
24477                                Slog.w(TAG,
24478                                        "Failed to set scheduling policy, thread does not exist:\n"
24479                                                + e);
24480                            } catch (SecurityException e) {
24481                                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
24482                            }
24483                        } else {
24484                            // Reset priority for top app UI and render threads
24485                            setThreadPriority(app.pid, 0);
24486                            if (app.renderThreadTid != 0) {
24487                                setThreadPriority(app.renderThreadTid, 0);
24488                            }
24489                        }
24490                    }
24491                } catch (Exception e) {
24492                    if (false) {
24493                        Slog.w(TAG, "Failed setting process group of " + app.pid
24494                                + " to " + app.curSchedGroup);
24495                        Slog.w(TAG, "at location", e);
24496                    }
24497                } finally {
24498                    Binder.restoreCallingIdentity(oldId);
24499                }
24500            }
24501        }
24502        if (app.repForegroundActivities != app.foregroundActivities) {
24503            app.repForegroundActivities = app.foregroundActivities;
24504            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
24505        }
24506        if (app.repProcState != app.curProcState) {
24507            app.repProcState = app.curProcState;
24508            if (app.thread != null) {
24509                try {
24510                    if (false) {
24511                        //RuntimeException h = new RuntimeException("here");
24512                        Slog.i(TAG, "Sending new process state " + app.repProcState
24513                                + " to " + app /*, h*/);
24514                    }
24515                    app.thread.setProcessState(app.repProcState);
24516                } catch (RemoteException e) {
24517                }
24518            }
24519        }
24520        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
24521                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
24522            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
24523                // Experimental code to more aggressively collect pss while
24524                // running test...  the problem is that this tends to collect
24525                // the data right when a process is transitioning between process
24526                // states, which will tend to give noisy data.
24527                long start = SystemClock.uptimeMillis();
24528                long startTime = SystemClock.currentThreadTimeMillis();
24529                long pss = Debug.getPss(app.pid, mTmpLong, null);
24530                long endTime = SystemClock.currentThreadTimeMillis();
24531                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1],
24532                        mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now);
24533                mPendingPssProcesses.remove(app);
24534                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
24535                        + " to " + app.curProcState + ": "
24536                        + (SystemClock.uptimeMillis()-start) + "ms");
24537            }
24538            app.lastStateTime = now;
24539            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24540                    app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24541            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
24542                    + ProcessList.makeProcStateString(app.setProcState) + " to "
24543                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
24544                    + (app.nextPssTime-now) + ": " + app);
24545        } else {
24546            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
24547                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
24548                    mTestPssMode)))) {
24549                if (requestPssLocked(app, app.setProcState)) {
24550                    app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24551                            app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24552                }
24553            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
24554                    "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
24555        }
24556        if (app.setProcState != app.curProcState) {
24557            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
24558                String msg = "Proc state change of " + app.processName
24559                        + " to " + ProcessList.makeProcStateString(app.curProcState)
24560                        + " (" + app.curProcState + ")" + ": " + app.adjType;
24561                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24562            }
24563            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
24564            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
24565            if (setImportant && !curImportant) {
24566                // This app is no longer something we consider important enough to allow to
24567                // use arbitrary amounts of battery power.  Note
24568                // its current CPU time to later know to kill it if
24569                // it is not behaving well.
24570                app.whenUnimportant = now;
24571                app.lastCpuTime = 0;
24572            }
24573            // Inform UsageStats of important process state change
24574            // Must be called before updating setProcState
24575            maybeUpdateUsageStatsLocked(app, nowElapsed);
24576
24577            app.setProcState = app.curProcState;
24578            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24579                app.notCachedSinceIdle = false;
24580            }
24581            if (!doingAll) {
24582                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
24583            } else {
24584                app.procStateChanged = true;
24585            }
24586        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
24587                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
24588            // For apps that sit around for a long time in the interactive state, we need
24589            // to report this at least once a day so they don't go idle.
24590            maybeUpdateUsageStatsLocked(app, nowElapsed);
24591        }
24592
24593        if (changes != 0) {
24594            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24595                    "Changes in " + app + ": " + changes);
24596            int i = mPendingProcessChanges.size()-1;
24597            ProcessChangeItem item = null;
24598            while (i >= 0) {
24599                item = mPendingProcessChanges.get(i);
24600                if (item.pid == app.pid) {
24601                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24602                            "Re-using existing item: " + item);
24603                    break;
24604                }
24605                i--;
24606            }
24607            if (i < 0) {
24608                // No existing item in pending changes; need a new one.
24609                final int NA = mAvailProcessChanges.size();
24610                if (NA > 0) {
24611                    item = mAvailProcessChanges.remove(NA-1);
24612                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24613                            "Retrieving available item: " + item);
24614                } else {
24615                    item = new ProcessChangeItem();
24616                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24617                            "Allocating new item: " + item);
24618                }
24619                item.changes = 0;
24620                item.pid = app.pid;
24621                item.uid = app.info.uid;
24622                if (mPendingProcessChanges.size() == 0) {
24623                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24624                            "*** Enqueueing dispatch processes changed!");
24625                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
24626                }
24627                mPendingProcessChanges.add(item);
24628            }
24629            item.changes |= changes;
24630            item.foregroundActivities = app.repForegroundActivities;
24631            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24632                    "Item " + Integer.toHexString(System.identityHashCode(item))
24633                    + " " + app.toShortString() + ": changes=" + item.changes
24634                    + " foreground=" + item.foregroundActivities
24635                    + " type=" + app.adjType + " source=" + app.adjSource
24636                    + " target=" + app.adjTarget);
24637        }
24638
24639        return success;
24640    }
24641
24642    private boolean isEphemeralLocked(int uid) {
24643        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
24644        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
24645            return false;
24646        }
24647        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
24648                packages[0]);
24649    }
24650
24651    @VisibleForTesting
24652    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
24653        final UidRecord.ChangeItem pendingChange;
24654        if (uidRec == null || uidRec.pendingChange == null) {
24655            if (mPendingUidChanges.size() == 0) {
24656                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24657                        "*** Enqueueing dispatch uid changed!");
24658                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
24659            }
24660            final int NA = mAvailUidChanges.size();
24661            if (NA > 0) {
24662                pendingChange = mAvailUidChanges.remove(NA-1);
24663                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24664                        "Retrieving available item: " + pendingChange);
24665            } else {
24666                pendingChange = new UidRecord.ChangeItem();
24667                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24668                        "Allocating new item: " + pendingChange);
24669            }
24670            if (uidRec != null) {
24671                uidRec.pendingChange = pendingChange;
24672                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
24673                    // If this uid is going away, and we haven't yet reported it is gone,
24674                    // then do so now.
24675                    change |= UidRecord.CHANGE_IDLE;
24676                }
24677            } else if (uid < 0) {
24678                throw new IllegalArgumentException("No UidRecord or uid");
24679            }
24680            pendingChange.uidRecord = uidRec;
24681            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
24682            mPendingUidChanges.add(pendingChange);
24683        } else {
24684            pendingChange = uidRec.pendingChange;
24685            // If there is no change in idle or active state, then keep whatever was pending.
24686            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
24687                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
24688                        | UidRecord.CHANGE_ACTIVE));
24689            }
24690            // If there is no change in cached or uncached state, then keep whatever was pending.
24691            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
24692                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
24693                        | UidRecord.CHANGE_UNCACHED));
24694            }
24695            // If this is a report of the UID being gone, then we shouldn't keep any previous
24696            // report of it being active or cached.  (That is, a gone uid is never active,
24697            // and never cached.)
24698            if ((change & UidRecord.CHANGE_GONE) != 0) {
24699                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
24700                if (!uidRec.idle) {
24701                    // If this uid is going away, and we haven't yet reported it is gone,
24702                    // then do so now.
24703                    change |= UidRecord.CHANGE_IDLE;
24704                }
24705            }
24706        }
24707        pendingChange.change = change;
24708        pendingChange.processState = uidRec != null
24709                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
24710        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
24711        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
24712        if (uidRec != null) {
24713            uidRec.lastReportedChange = change;
24714            uidRec.updateLastDispatchedProcStateSeq(change);
24715        }
24716
24717        // Directly update the power manager, since we sit on top of it and it is critical
24718        // it be kept in sync (so wake locks will be held as soon as appropriate).
24719        if (mLocalPowerManager != null) {
24720            // TO DO: dispatch cached/uncached changes here, so we don't need to report
24721            // all proc state changes.
24722            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
24723                mLocalPowerManager.uidActive(pendingChange.uid);
24724            }
24725            if ((change & UidRecord.CHANGE_IDLE) != 0) {
24726                mLocalPowerManager.uidIdle(pendingChange.uid);
24727            }
24728            if ((change & UidRecord.CHANGE_GONE) != 0) {
24729                mLocalPowerManager.uidGone(pendingChange.uid);
24730            } else {
24731                mLocalPowerManager.updateUidProcState(pendingChange.uid,
24732                        pendingChange.processState);
24733            }
24734        }
24735    }
24736
24737    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
24738            String authority) {
24739        if (app == null) return;
24740        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
24741            UserState userState = mUserController.getStartedUserState(app.userId);
24742            if (userState == null) return;
24743            final long now = SystemClock.elapsedRealtime();
24744            Long lastReported = userState.mProviderLastReportedFg.get(authority);
24745            if (lastReported == null || lastReported < now - 60 * 1000L) {
24746                if (mSystemReady) {
24747                    // Cannot touch the user stats if not system ready
24748                    mUsageStatsService.reportContentProviderUsage(
24749                            authority, providerPkgName, app.userId);
24750                }
24751                userState.mProviderLastReportedFg.put(authority, now);
24752            }
24753        }
24754    }
24755
24756    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
24757        if (DEBUG_USAGE_STATS) {
24758            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
24759                    + "] state changes: old = " + app.setProcState + ", new = "
24760                    + app.curProcState);
24761        }
24762        if (mUsageStatsService == null) {
24763            return;
24764        }
24765        boolean isInteraction;
24766        // To avoid some abuse patterns, we are going to be careful about what we consider
24767        // to be an app interaction.  Being the top activity doesn't count while the display
24768        // is sleeping, nor do short foreground services.
24769        if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
24770            isInteraction = true;
24771            app.fgInteractionTime = 0;
24772        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
24773            if (app.fgInteractionTime == 0) {
24774                app.fgInteractionTime = nowElapsed;
24775                isInteraction = false;
24776            } else {
24777                isInteraction = nowElapsed > app.fgInteractionTime
24778                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
24779            }
24780        } else {
24781            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
24782            app.fgInteractionTime = 0;
24783        }
24784        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
24785                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
24786            app.interactionEventTime = nowElapsed;
24787            String[] packages = app.getPackageList();
24788            if (packages != null) {
24789                for (int i = 0; i < packages.length; i++) {
24790                    mUsageStatsService.reportEvent(packages[i], app.userId,
24791                            UsageEvents.Event.SYSTEM_INTERACTION);
24792                }
24793            }
24794        }
24795        app.reportedInteraction = isInteraction;
24796        if (!isInteraction) {
24797            app.interactionEventTime = 0;
24798        }
24799    }
24800
24801    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
24802        if (proc.thread != null) {
24803            if (proc.baseProcessTracker != null) {
24804                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
24805            }
24806        }
24807    }
24808
24809    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
24810            ProcessRecord TOP_APP, boolean doingAll, long now) {
24811        if (app.thread == null) {
24812            return false;
24813        }
24814
24815        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
24816
24817        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
24818    }
24819
24820    @GuardedBy("this")
24821    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
24822            boolean oomAdj) {
24823        if (isForeground != proc.foregroundServices) {
24824            proc.foregroundServices = isForeground;
24825            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
24826                    proc.info.uid);
24827            if (isForeground) {
24828                if (curProcs == null) {
24829                    curProcs = new ArrayList<ProcessRecord>();
24830                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
24831                }
24832                if (!curProcs.contains(proc)) {
24833                    curProcs.add(proc);
24834                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
24835                            proc.info.packageName, proc.info.uid);
24836                }
24837            } else {
24838                if (curProcs != null) {
24839                    if (curProcs.remove(proc)) {
24840                        mBatteryStatsService.noteEvent(
24841                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
24842                                proc.info.packageName, proc.info.uid);
24843                        if (curProcs.size() <= 0) {
24844                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
24845                        }
24846                    }
24847                }
24848            }
24849            if (oomAdj) {
24850                updateOomAdjLocked();
24851            }
24852        }
24853    }
24854
24855    private final ActivityRecord resumedAppLocked() {
24856        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
24857        String pkg;
24858        int uid;
24859        if (act != null) {
24860            pkg = act.packageName;
24861            uid = act.info.applicationInfo.uid;
24862        } else {
24863            pkg = null;
24864            uid = -1;
24865        }
24866        // Has the UID or resumed package name changed?
24867        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
24868                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
24869            if (mCurResumedPackage != null) {
24870                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
24871                        mCurResumedPackage, mCurResumedUid);
24872            }
24873            mCurResumedPackage = pkg;
24874            mCurResumedUid = uid;
24875            if (mCurResumedPackage != null) {
24876                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
24877                        mCurResumedPackage, mCurResumedUid);
24878            }
24879        }
24880        return act;
24881    }
24882
24883    /**
24884     * Update OomAdj for a specific process.
24885     * @param app The process to update
24886     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
24887     *                  if necessary, or skip.
24888     * @return whether updateOomAdjLocked(app) was successful.
24889     */
24890    @GuardedBy("this")
24891    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
24892        final ActivityRecord TOP_ACT = resumedAppLocked();
24893        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24894        final boolean wasCached = app.cached;
24895
24896        mAdjSeq++;
24897
24898        // This is the desired cached adjusment we want to tell it to use.
24899        // If our app is currently cached, we know it, and that is it.  Otherwise,
24900        // we don't know it yet, and it needs to now be cached we will then
24901        // need to do a complete oom adj.
24902        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
24903                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
24904        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
24905                SystemClock.uptimeMillis());
24906        if (oomAdjAll
24907                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
24908            // Changed to/from cached state, so apps after it in the LRU
24909            // list may also be changed.
24910            updateOomAdjLocked();
24911        }
24912        return success;
24913    }
24914
24915    @GuardedBy("this")
24916    final void updateOomAdjLocked() {
24917        final ActivityRecord TOP_ACT = resumedAppLocked();
24918        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24919        final long now = SystemClock.uptimeMillis();
24920        final long nowElapsed = SystemClock.elapsedRealtime();
24921        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
24922        final int N = mLruProcesses.size();
24923
24924        if (false) {
24925            RuntimeException e = new RuntimeException();
24926            e.fillInStackTrace();
24927            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
24928        }
24929
24930        // Reset state in all uid records.
24931        for (int i=mActiveUids.size()-1; i>=0; i--) {
24932            final UidRecord uidRec = mActiveUids.valueAt(i);
24933            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24934                    "Starting update of " + uidRec);
24935            uidRec.reset();
24936        }
24937
24938        mStackSupervisor.rankTaskLayersIfNeeded();
24939
24940        mAdjSeq++;
24941        mNewNumServiceProcs = 0;
24942        mNewNumAServiceProcs = 0;
24943
24944        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
24945        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
24946
24947        // Let's determine how many processes we have running vs.
24948        // how many slots we have for background processes; we may want
24949        // to put multiple processes in a slot of there are enough of
24950        // them.
24951        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
24952                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
24953        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
24954        if (numEmptyProcs > cachedProcessLimit) {
24955            // If there are more empty processes than our limit on cached
24956            // processes, then use the cached process limit for the factor.
24957            // This ensures that the really old empty processes get pushed
24958            // down to the bottom, so if we are running low on memory we will
24959            // have a better chance at keeping around more cached processes
24960            // instead of a gazillion empty processes.
24961            numEmptyProcs = cachedProcessLimit;
24962        }
24963        int emptyFactor = numEmptyProcs/numSlots;
24964        if (emptyFactor < 1) emptyFactor = 1;
24965        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
24966        if (cachedFactor < 1) cachedFactor = 1;
24967        int stepCached = 0;
24968        int stepEmpty = 0;
24969        int numCached = 0;
24970        int numEmpty = 0;
24971        int numTrimming = 0;
24972
24973        mNumNonCachedProcs = 0;
24974        mNumCachedHiddenProcs = 0;
24975
24976        // First update the OOM adjustment for each of the
24977        // application processes based on their current state.
24978        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
24979        int nextCachedAdj = curCachedAdj+1;
24980        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
24981        int nextEmptyAdj = curEmptyAdj+2;
24982
24983        boolean retryCycles = false;
24984
24985        // need to reset cycle state before calling computeOomAdjLocked because of service connections
24986        for (int i=N-1; i>=0; i--) {
24987            ProcessRecord app = mLruProcesses.get(i);
24988            app.containsCycle = false;
24989        }
24990        for (int i=N-1; i>=0; i--) {
24991            ProcessRecord app = mLruProcesses.get(i);
24992            if (!app.killedByAm && app.thread != null) {
24993                app.procStateChanged = false;
24994                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
24995
24996                // if any app encountered a cycle, we need to perform an additional loop later
24997                retryCycles |= app.containsCycle;
24998
24999                // If we haven't yet assigned the final cached adj
25000                // to the process, do that now.
25001                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
25002                    switch (app.curProcState) {
25003                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
25004                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
25005                        case ActivityManager.PROCESS_STATE_CACHED_RECENT:
25006                            // This process is a cached process holding activities...
25007                            // assign it the next cached value for that type, and then
25008                            // step that cached level.
25009                            app.curRawAdj = curCachedAdj;
25010                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
25011                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
25012                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
25013                                    + ")");
25014                            if (curCachedAdj != nextCachedAdj) {
25015                                stepCached++;
25016                                if (stepCached >= cachedFactor) {
25017                                    stepCached = 0;
25018                                    curCachedAdj = nextCachedAdj;
25019                                    nextCachedAdj += 2;
25020                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
25021                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
25022                                    }
25023                                }
25024                            }
25025                            break;
25026                        default:
25027                            // For everything else, assign next empty cached process
25028                            // level and bump that up.  Note that this means that
25029                            // long-running services that have dropped down to the
25030                            // cached level will be treated as empty (since their process
25031                            // state is still as a service), which is what we want.
25032                            app.curRawAdj = curEmptyAdj;
25033                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
25034                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
25035                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
25036                                    + ")");
25037                            if (curEmptyAdj != nextEmptyAdj) {
25038                                stepEmpty++;
25039                                if (stepEmpty >= emptyFactor) {
25040                                    stepEmpty = 0;
25041                                    curEmptyAdj = nextEmptyAdj;
25042                                    nextEmptyAdj += 2;
25043                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
25044                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
25045                                    }
25046                                }
25047                            }
25048                            break;
25049                    }
25050                }
25051
25052
25053            }
25054        }
25055
25056        // Cycle strategy:
25057        // - Retry computing any process that has encountered a cycle.
25058        // - Continue retrying until no process was promoted.
25059        // - Iterate from least important to most important.
25060        int cycleCount = 0;
25061        while (retryCycles) {
25062            cycleCount++;
25063            retryCycles = false;
25064
25065            for (int i=0; i<N; i++) {
25066                ProcessRecord app = mLruProcesses.get(i);
25067                if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
25068                    app.adjSeq--;
25069                    app.completedAdjSeq--;
25070                }
25071            }
25072
25073            for (int i=0; i<N; i++) {
25074                ProcessRecord app = mLruProcesses.get(i);
25075                if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
25076                    if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now)) {
25077                        retryCycles = true;
25078                    }
25079                }
25080            }
25081        }
25082        for (int i=N-1; i>=0; i--) {
25083            ProcessRecord app = mLruProcesses.get(i);
25084            if (!app.killedByAm && app.thread != null) {
25085                applyOomAdjLocked(app, true, now, nowElapsed);
25086
25087                // Count the number of process types.
25088                switch (app.curProcState) {
25089                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
25090                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
25091                        mNumCachedHiddenProcs++;
25092                        numCached++;
25093                        if (numCached > cachedProcessLimit) {
25094                            app.kill("cached #" + numCached, true);
25095                        }
25096                        break;
25097                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
25098                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
25099                                && app.lastActivityTime < oldTime) {
25100                            app.kill("empty for "
25101                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
25102                                    / 1000) + "s", true);
25103                        } else {
25104                            numEmpty++;
25105                            if (numEmpty > emptyProcessLimit) {
25106                                app.kill("empty #" + numEmpty, true);
25107                            }
25108                        }
25109                        break;
25110                    default:
25111                        mNumNonCachedProcs++;
25112                        break;
25113                }
25114
25115                if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
25116                    // If this is an isolated process, there are no services
25117                    // running in it, and it's not a special process with a
25118                    // custom entry point, then the process is no longer
25119                    // needed.  We agressively kill these because we can by
25120                    // definition not re-use the same process again, and it is
25121                    // good to avoid having whatever code was running in them
25122                    // left sitting around after no longer needed.
25123                    app.kill("isolated not needed", true);
25124                } else {
25125                    // Keeping this process, update its uid.
25126                    final UidRecord uidRec = app.uidRecord;
25127                    if (uidRec != null) {
25128                        uidRec.ephemeral = app.info.isInstantApp();
25129                        if (uidRec.curProcState > app.curProcState) {
25130                            uidRec.curProcState = app.curProcState;
25131                        }
25132                        if (app.foregroundServices) {
25133                            uidRec.foregroundServices = true;
25134                        }
25135                    }
25136                }
25137
25138                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
25139                        && !app.killedByAm) {
25140                    numTrimming++;
25141                }
25142            }
25143        }
25144
25145        incrementProcStateSeqAndNotifyAppsLocked();
25146
25147        mNumServiceProcs = mNewNumServiceProcs;
25148
25149        // Now determine the memory trimming level of background processes.
25150        // Unfortunately we need to start at the back of the list to do this
25151        // properly.  We only do this if the number of background apps we
25152        // are managing to keep around is less than half the maximum we desire;
25153        // if we are keeping a good number around, we'll let them use whatever
25154        // memory they want.
25155        final int numCachedAndEmpty = numCached + numEmpty;
25156        int memFactor;
25157        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
25158                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
25159            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
25160                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
25161            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
25162                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
25163            } else {
25164                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
25165            }
25166        } else {
25167            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
25168        }
25169        // We always allow the memory level to go up (better).  We only allow it to go
25170        // down if we are in a state where that is allowed, *and* the total number of processes
25171        // has gone down since last time.
25172        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
25173                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
25174                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
25175        if (memFactor > mLastMemoryLevel) {
25176            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
25177                memFactor = mLastMemoryLevel;
25178                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
25179            }
25180        }
25181        if (memFactor != mLastMemoryLevel) {
25182            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
25183        }
25184        mLastMemoryLevel = memFactor;
25185        mLastNumProcesses = mLruProcesses.size();
25186        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
25187        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
25188        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
25189            if (mLowRamStartTime == 0) {
25190                mLowRamStartTime = now;
25191            }
25192            int step = 0;
25193            int fgTrimLevel;
25194            switch (memFactor) {
25195                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
25196                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
25197                    break;
25198                case ProcessStats.ADJ_MEM_FACTOR_LOW:
25199                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
25200                    break;
25201                default:
25202                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
25203                    break;
25204            }
25205            int factor = numTrimming/3;
25206            int minFactor = 2;
25207            if (mHomeProcess != null) minFactor++;
25208            if (mPreviousProcess != null) minFactor++;
25209            if (factor < minFactor) factor = minFactor;
25210            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
25211            for (int i=N-1; i>=0; i--) {
25212                ProcessRecord app = mLruProcesses.get(i);
25213                if (allChanged || app.procStateChanged) {
25214                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
25215                    app.procStateChanged = false;
25216                }
25217                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
25218                        && !app.killedByAm) {
25219                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
25220                        try {
25221                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25222                                    "Trimming memory of " + app.processName + " to " + curLevel);
25223                            app.thread.scheduleTrimMemory(curLevel);
25224                        } catch (RemoteException e) {
25225                        }
25226                        if (false) {
25227                            // For now we won't do this; our memory trimming seems
25228                            // to be good enough at this point that destroying
25229                            // activities causes more harm than good.
25230                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
25231                                    && app != mHomeProcess && app != mPreviousProcess) {
25232                                // Need to do this on its own message because the stack may not
25233                                // be in a consistent state at this point.
25234                                // For these apps we will also finish their activities
25235                                // to help them free memory.
25236                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
25237                            }
25238                        }
25239                    }
25240                    app.trimMemoryLevel = curLevel;
25241                    step++;
25242                    if (step >= factor) {
25243                        step = 0;
25244                        switch (curLevel) {
25245                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
25246                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
25247                                break;
25248                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
25249                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
25250                                break;
25251                        }
25252                    }
25253                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
25254                        && !app.killedByAm) {
25255                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
25256                            && app.thread != null) {
25257                        try {
25258                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25259                                    "Trimming memory of heavy-weight " + app.processName
25260                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
25261                            app.thread.scheduleTrimMemory(
25262                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
25263                        } catch (RemoteException e) {
25264                        }
25265                    }
25266                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
25267                } else {
25268                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
25269                            || app.systemNoUi) && app.pendingUiClean) {
25270                        // If this application is now in the background and it
25271                        // had done UI, then give it the special trim level to
25272                        // have it free UI resources.
25273                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
25274                        if (app.trimMemoryLevel < level && app.thread != null) {
25275                            try {
25276                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25277                                        "Trimming memory of bg-ui " + app.processName
25278                                        + " to " + level);
25279                                app.thread.scheduleTrimMemory(level);
25280                            } catch (RemoteException e) {
25281                            }
25282                        }
25283                        app.pendingUiClean = false;
25284                    }
25285                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
25286                        try {
25287                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25288                                    "Trimming memory of fg " + app.processName
25289                                    + " to " + fgTrimLevel);
25290                            app.thread.scheduleTrimMemory(fgTrimLevel);
25291                        } catch (RemoteException e) {
25292                        }
25293                    }
25294                    app.trimMemoryLevel = fgTrimLevel;
25295                }
25296            }
25297        } else {
25298            if (mLowRamStartTime != 0) {
25299                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
25300                mLowRamStartTime = 0;
25301            }
25302            for (int i=N-1; i>=0; i--) {
25303                ProcessRecord app = mLruProcesses.get(i);
25304                if (allChanged || app.procStateChanged) {
25305                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
25306                    app.procStateChanged = false;
25307                }
25308                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
25309                        || app.systemNoUi) && app.pendingUiClean) {
25310                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
25311                            && app.thread != null) {
25312                        try {
25313                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
25314                                    "Trimming memory of ui hidden " + app.processName
25315                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
25316                            app.thread.scheduleTrimMemory(
25317                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
25318                        } catch (RemoteException e) {
25319                        }
25320                    }
25321                    app.pendingUiClean = false;
25322                }
25323                app.trimMemoryLevel = 0;
25324            }
25325        }
25326
25327        if (mAlwaysFinishActivities) {
25328            // Need to do this on its own message because the stack may not
25329            // be in a consistent state at this point.
25330            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
25331        }
25332
25333        if (allChanged) {
25334            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
25335        }
25336
25337        ArrayList<UidRecord> becameIdle = null;
25338
25339        // Update from any uid changes.
25340        if (mLocalPowerManager != null) {
25341            mLocalPowerManager.startUidChanges();
25342        }
25343        for (int i=mActiveUids.size()-1; i>=0; i--) {
25344            final UidRecord uidRec = mActiveUids.valueAt(i);
25345            int uidChange = UidRecord.CHANGE_PROCSTATE;
25346            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
25347                    && (uidRec.setProcState != uidRec.curProcState
25348                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
25349                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
25350                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
25351                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
25352                        + " to " + uidRec.curWhitelist);
25353                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
25354                        && !uidRec.curWhitelist) {
25355                    // UID is now in the background (and not on the temp whitelist).  Was it
25356                    // previously in the foreground (or on the temp whitelist)?
25357                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
25358                            || uidRec.setWhitelist) {
25359                        uidRec.lastBackgroundTime = nowElapsed;
25360                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
25361                            // Note: the background settle time is in elapsed realtime, while
25362                            // the handler time base is uptime.  All this means is that we may
25363                            // stop background uids later than we had intended, but that only
25364                            // happens because the device was sleeping so we are okay anyway.
25365                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
25366                                    mConstants.BACKGROUND_SETTLE_TIME);
25367                        }
25368                    }
25369                    if (uidRec.idle && !uidRec.setIdle) {
25370                        uidChange = UidRecord.CHANGE_IDLE;
25371                        if (becameIdle == null) {
25372                            becameIdle = new ArrayList<>();
25373                        }
25374                        becameIdle.add(uidRec);
25375                    }
25376                } else {
25377                    if (uidRec.idle) {
25378                        uidChange = UidRecord.CHANGE_ACTIVE;
25379                        EventLogTags.writeAmUidActive(uidRec.uid);
25380                        uidRec.idle = false;
25381                    }
25382                    uidRec.lastBackgroundTime = 0;
25383                }
25384                final boolean wasCached = uidRec.setProcState
25385                        > ActivityManager.PROCESS_STATE_RECEIVER;
25386                final boolean isCached = uidRec.curProcState
25387                        > ActivityManager.PROCESS_STATE_RECEIVER;
25388                if (wasCached != isCached ||
25389                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
25390                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
25391                }
25392                uidRec.setProcState = uidRec.curProcState;
25393                uidRec.setWhitelist = uidRec.curWhitelist;
25394                uidRec.setIdle = uidRec.idle;
25395                enqueueUidChangeLocked(uidRec, -1, uidChange);
25396                noteUidProcessState(uidRec.uid, uidRec.curProcState);
25397                if (uidRec.foregroundServices) {
25398                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
25399                }
25400            }
25401        }
25402        if (mLocalPowerManager != null) {
25403            mLocalPowerManager.finishUidChanges();
25404        }
25405
25406        if (becameIdle != null) {
25407            // If we have any new uids that became idle this time, we need to make sure
25408            // they aren't left with running services.
25409            for (int i = becameIdle.size() - 1; i >= 0; i--) {
25410                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
25411            }
25412        }
25413
25414        if (mProcessStats.shouldWriteNowLocked(now)) {
25415            mHandler.post(new Runnable() {
25416                @Override public void run() {
25417                    synchronized (ActivityManagerService.this) {
25418                        mProcessStats.writeStateAsyncLocked();
25419                    }
25420                }
25421            });
25422        }
25423
25424        if (DEBUG_OOM_ADJ) {
25425            final long duration = SystemClock.uptimeMillis() - now;
25426            if (false) {
25427                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
25428                        new RuntimeException("here").fillInStackTrace());
25429            } else {
25430                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
25431            }
25432        }
25433    }
25434
25435    @Override
25436    public void makePackageIdle(String packageName, int userId) {
25437        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
25438                != PackageManager.PERMISSION_GRANTED) {
25439            String msg = "Permission Denial: makePackageIdle() from pid="
25440                    + Binder.getCallingPid()
25441                    + ", uid=" + Binder.getCallingUid()
25442                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
25443            Slog.w(TAG, msg);
25444            throw new SecurityException(msg);
25445        }
25446        final int callingPid = Binder.getCallingPid();
25447        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
25448                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
25449        long callingId = Binder.clearCallingIdentity();
25450        synchronized(this) {
25451            try {
25452                IPackageManager pm = AppGlobals.getPackageManager();
25453                int pkgUid = -1;
25454                try {
25455                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
25456                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
25457                } catch (RemoteException e) {
25458                }
25459                if (pkgUid == -1) {
25460                    throw new IllegalArgumentException("Unknown package name " + packageName);
25461                }
25462
25463                if (mLocalPowerManager != null) {
25464                    mLocalPowerManager.startUidChanges();
25465                }
25466                final int appId = UserHandle.getAppId(pkgUid);
25467                final int N = mActiveUids.size();
25468                for (int i=N-1; i>=0; i--) {
25469                    final UidRecord uidRec = mActiveUids.valueAt(i);
25470                    final long bgTime = uidRec.lastBackgroundTime;
25471                    if (bgTime > 0 && !uidRec.idle) {
25472                        if (UserHandle.getAppId(uidRec.uid) == appId) {
25473                            if (userId == UserHandle.USER_ALL ||
25474                                    userId == UserHandle.getUserId(uidRec.uid)) {
25475                                EventLogTags.writeAmUidIdle(uidRec.uid);
25476                                uidRec.idle = true;
25477                                uidRec.setIdle = true;
25478                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
25479                                        + " from package " + packageName + " user " + userId);
25480                                doStopUidLocked(uidRec.uid, uidRec);
25481                            }
25482                        }
25483                    }
25484                }
25485            } finally {
25486                if (mLocalPowerManager != null) {
25487                    mLocalPowerManager.finishUidChanges();
25488                }
25489                Binder.restoreCallingIdentity(callingId);
25490            }
25491        }
25492    }
25493
25494    final void idleUids() {
25495        synchronized (this) {
25496            final int N = mActiveUids.size();
25497            if (N <= 0) {
25498                return;
25499            }
25500            final long nowElapsed = SystemClock.elapsedRealtime();
25501            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
25502            long nextTime = 0;
25503            if (mLocalPowerManager != null) {
25504                mLocalPowerManager.startUidChanges();
25505            }
25506            for (int i=N-1; i>=0; i--) {
25507                final UidRecord uidRec = mActiveUids.valueAt(i);
25508                final long bgTime = uidRec.lastBackgroundTime;
25509                if (bgTime > 0 && !uidRec.idle) {
25510                    if (bgTime <= maxBgTime) {
25511                        EventLogTags.writeAmUidIdle(uidRec.uid);
25512                        uidRec.idle = true;
25513                        uidRec.setIdle = true;
25514                        doStopUidLocked(uidRec.uid, uidRec);
25515                    } else {
25516                        if (nextTime == 0 || nextTime > bgTime) {
25517                            nextTime = bgTime;
25518                        }
25519                    }
25520                }
25521            }
25522            if (mLocalPowerManager != null) {
25523                mLocalPowerManager.finishUidChanges();
25524            }
25525            if (nextTime > 0) {
25526                mHandler.removeMessages(IDLE_UIDS_MSG);
25527                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
25528                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
25529            }
25530        }
25531    }
25532
25533    /**
25534     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
25535     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
25536     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
25537     */
25538    @VisibleForTesting
25539    @GuardedBy("this")
25540    void incrementProcStateSeqAndNotifyAppsLocked() {
25541        if (mWaitForNetworkTimeoutMs <= 0) {
25542            return;
25543        }
25544        // Used for identifying which uids need to block for network.
25545        ArrayList<Integer> blockingUids = null;
25546        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
25547            final UidRecord uidRec = mActiveUids.valueAt(i);
25548            // If the network is not restricted for uid, then nothing to do here.
25549            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
25550                continue;
25551            }
25552            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
25553                continue;
25554            }
25555            // If process state is not changed, then there's nothing to do.
25556            if (uidRec.setProcState == uidRec.curProcState) {
25557                continue;
25558            }
25559            final int blockState = getBlockStateForUid(uidRec);
25560            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
25561            // there's nothing the app needs to do in this scenario.
25562            if (blockState == NETWORK_STATE_NO_CHANGE) {
25563                continue;
25564            }
25565            synchronized (uidRec.networkStateLock) {
25566                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
25567                if (blockState == NETWORK_STATE_BLOCK) {
25568                    if (blockingUids == null) {
25569                        blockingUids = new ArrayList<>();
25570                    }
25571                    blockingUids.add(uidRec.uid);
25572                } else {
25573                    if (DEBUG_NETWORK) {
25574                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
25575                                + " threads for uid: " + uidRec);
25576                    }
25577                    if (uidRec.waitingForNetwork) {
25578                        uidRec.networkStateLock.notifyAll();
25579                    }
25580                }
25581            }
25582        }
25583
25584        // There are no uids that need to block, so nothing more to do.
25585        if (blockingUids == null) {
25586            return;
25587        }
25588
25589        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
25590            final ProcessRecord app = mLruProcesses.get(i);
25591            if (!blockingUids.contains(app.uid)) {
25592                continue;
25593            }
25594            if (!app.killedByAm && app.thread != null) {
25595                final UidRecord uidRec = mActiveUids.get(app.uid);
25596                try {
25597                    if (DEBUG_NETWORK) {
25598                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
25599                                + uidRec);
25600                    }
25601                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
25602                } catch (RemoteException ignored) {
25603                }
25604            }
25605        }
25606    }
25607
25608    /**
25609     * Checks if the uid is coming from background to foreground or vice versa and returns
25610     * appropriate block state based on this.
25611     *
25612     * @return blockState based on whether the uid is coming from background to foreground or
25613     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
25614     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
25615     *         {@link #NETWORK_STATE_NO_CHANGE}.
25616     */
25617    @VisibleForTesting
25618    int getBlockStateForUid(UidRecord uidRec) {
25619        // Denotes whether uid's process state is currently allowed network access.
25620        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
25621                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
25622        // Denotes whether uid's process state was previously allowed network access.
25623        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
25624                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
25625
25626        // When the uid is coming to foreground, AMS should inform the app thread that it should
25627        // block for the network rules to get updated before launching an activity.
25628        if (!wasAllowed && isAllowed) {
25629            return NETWORK_STATE_BLOCK;
25630        }
25631        // When the uid is going to background, AMS should inform the app thread that if an
25632        // activity launch is blocked for the network rules to get updated, it should be unblocked.
25633        if (wasAllowed && !isAllowed) {
25634            return NETWORK_STATE_UNBLOCK;
25635        }
25636        return NETWORK_STATE_NO_CHANGE;
25637    }
25638
25639    final void runInBackgroundDisabled(int uid) {
25640        synchronized (this) {
25641            UidRecord uidRec = mActiveUids.get(uid);
25642            if (uidRec != null) {
25643                // This uid is actually running...  should it be considered background now?
25644                if (uidRec.idle) {
25645                    doStopUidLocked(uidRec.uid, uidRec);
25646                }
25647            } else {
25648                // This uid isn't actually running...  still send a report about it being "stopped".
25649                doStopUidLocked(uid, null);
25650            }
25651        }
25652    }
25653
25654    /**
25655     * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
25656     */
25657    void doStopUidForIdleUidsLocked() {
25658        final int size = mActiveUids.size();
25659        for (int i = 0; i < size; i++) {
25660            final int uid = mActiveUids.keyAt(i);
25661            if (UserHandle.isCore(uid)) {
25662                continue;
25663            }
25664            final UidRecord uidRec = mActiveUids.valueAt(i);
25665            if (!uidRec.idle) {
25666                continue;
25667            }
25668            doStopUidLocked(uidRec.uid, uidRec);
25669        }
25670    }
25671
25672    final void doStopUidLocked(int uid, final UidRecord uidRec) {
25673        mServices.stopInBackgroundLocked(uid);
25674        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
25675    }
25676
25677    /**
25678     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25679     */
25680    @GuardedBy("this")
25681    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
25682            long duration, String tag) {
25683        if (DEBUG_WHITELISTS) {
25684            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
25685                    + targetUid + ", " + duration + ")");
25686        }
25687
25688        synchronized (mPidsSelfLocked) {
25689            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
25690            if (pr == null) {
25691                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
25692                        + callerPid);
25693                return;
25694            }
25695            if (!pr.whitelistManager) {
25696                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
25697                        != PackageManager.PERMISSION_GRANTED) {
25698                    if (DEBUG_WHITELISTS) {
25699                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
25700                                + ": pid " + callerPid + " is not allowed");
25701                    }
25702                    return;
25703                }
25704            }
25705        }
25706
25707        tempWhitelistUidLocked(targetUid, duration, tag);
25708    }
25709
25710    /**
25711     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25712     */
25713    @GuardedBy("this")
25714    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
25715        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
25716        setUidTempWhitelistStateLocked(targetUid, true);
25717        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
25718    }
25719
25720    void pushTempWhitelist() {
25721        final int N;
25722        final PendingTempWhitelist[] list;
25723
25724        // First copy out the pending changes...  we need to leave them in the map for now,
25725        // in case someone needs to check what is coming up while we don't have the lock held.
25726        synchronized(this) {
25727            N = mPendingTempWhitelist.size();
25728            list = new PendingTempWhitelist[N];
25729            for (int i = 0; i < N; i++) {
25730                list[i] = mPendingTempWhitelist.valueAt(i);
25731            }
25732        }
25733
25734        // Now safely dispatch changes to device idle controller.
25735        for (int i = 0; i < N; i++) {
25736            PendingTempWhitelist ptw = list[i];
25737            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
25738                    ptw.duration, true, ptw.tag);
25739        }
25740
25741        // And now we can safely remove them from the map.
25742        synchronized(this) {
25743            for (int i = 0; i < N; i++) {
25744                PendingTempWhitelist ptw = list[i];
25745                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
25746                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
25747                    mPendingTempWhitelist.removeAt(index);
25748                }
25749            }
25750        }
25751    }
25752
25753    @GuardedBy("this")
25754    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
25755        boolean changed = false;
25756        for (int i=mActiveUids.size()-1; i>=0; i--) {
25757            final UidRecord uidRec = mActiveUids.valueAt(i);
25758            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
25759                uidRec.curWhitelist = onWhitelist;
25760                changed = true;
25761            }
25762        }
25763        if (changed) {
25764            updateOomAdjLocked();
25765        }
25766    }
25767
25768    @GuardedBy("this")
25769    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
25770        boolean changed = false;
25771        final UidRecord uidRec = mActiveUids.get(uid);
25772        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
25773            uidRec.curWhitelist = onWhitelist;
25774            updateOomAdjLocked();
25775        }
25776    }
25777
25778    final void trimApplications() {
25779        synchronized (this) {
25780            trimApplicationsLocked();
25781        }
25782    }
25783
25784    final void trimApplicationsLocked() {
25785        // First remove any unused application processes whose package
25786        // has been removed.
25787        for (int i=mRemovedProcesses.size()-1; i>=0; i--) {
25788            final ProcessRecord app = mRemovedProcesses.get(i);
25789            if (app.activities.size() == 0 && app.recentTasks.size() == 0
25790                    && app.curReceivers.isEmpty() && app.services.size() == 0) {
25791                Slog.i(
25792                    TAG, "Exiting empty application process "
25793                    + app.toShortString() + " ("
25794                    + (app.thread != null ? app.thread.asBinder() : null)
25795                    + ")\n");
25796                if (app.pid > 0 && app.pid != MY_PID) {
25797                    app.kill("empty", false);
25798                } else if (app.thread != null) {
25799                    try {
25800                        app.thread.scheduleExit();
25801                    } catch (Exception e) {
25802                        // Ignore exceptions.
25803                    }
25804                }
25805                cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
25806                mRemovedProcesses.remove(i);
25807
25808                if (app.persistent) {
25809                    addAppLocked(app.info, null, false, null /* ABI override */);
25810                }
25811            }
25812        }
25813
25814        // Now update the oom adj for all processes. Don't skip this, since other callers
25815        // might be depending on it.
25816        updateOomAdjLocked();
25817    }
25818
25819    /** This method sends the specified signal to each of the persistent apps */
25820    public void signalPersistentProcesses(int sig) throws RemoteException {
25821        if (sig != SIGNAL_USR1) {
25822            throw new SecurityException("Only SIGNAL_USR1 is allowed");
25823        }
25824
25825        synchronized (this) {
25826            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
25827                    != PackageManager.PERMISSION_GRANTED) {
25828                throw new SecurityException("Requires permission "
25829                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
25830            }
25831
25832            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
25833                ProcessRecord r = mLruProcesses.get(i);
25834                if (r.thread != null && r.persistent) {
25835                    sendSignal(r.pid, sig);
25836                }
25837            }
25838        }
25839    }
25840
25841    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
25842        if (proc == null || proc == mProfileProc) {
25843            proc = mProfileProc;
25844            profileType = mProfileType;
25845            clearProfilerLocked();
25846        }
25847        if (proc == null) {
25848            return;
25849        }
25850        try {
25851            proc.thread.profilerControl(false, null, profileType);
25852        } catch (RemoteException e) {
25853            throw new IllegalStateException("Process disappeared");
25854        }
25855    }
25856
25857    private void clearProfilerLocked() {
25858        if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
25859            try {
25860                mProfilerInfo.profileFd.close();
25861            } catch (IOException e) {
25862            }
25863        }
25864        mProfileApp = null;
25865        mProfileProc = null;
25866        mProfilerInfo = null;
25867    }
25868
25869    public boolean profileControl(String process, int userId, boolean start,
25870            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
25871
25872        try {
25873            synchronized (this) {
25874                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
25875                // its own permission.
25876                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25877                        != PackageManager.PERMISSION_GRANTED) {
25878                    throw new SecurityException("Requires permission "
25879                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25880                }
25881
25882                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
25883                    throw new IllegalArgumentException("null profile info or fd");
25884                }
25885
25886                ProcessRecord proc = null;
25887                if (process != null) {
25888                    proc = findProcessLocked(process, userId, "profileControl");
25889                }
25890
25891                if (start && (proc == null || proc.thread == null)) {
25892                    throw new IllegalArgumentException("Unknown process: " + process);
25893                }
25894
25895                if (start) {
25896                    stopProfilerLocked(null, 0);
25897                    setProfileApp(proc.info, proc.processName, profilerInfo);
25898                    mProfileProc = proc;
25899                    mProfileType = profileType;
25900                    ParcelFileDescriptor fd = profilerInfo.profileFd;
25901                    try {
25902                        fd = fd.dup();
25903                    } catch (IOException e) {
25904                        fd = null;
25905                    }
25906                    profilerInfo.profileFd = fd;
25907                    proc.thread.profilerControl(start, profilerInfo, profileType);
25908                    fd = null;
25909                    try {
25910                        mProfilerInfo.profileFd.close();
25911                    } catch (IOException e) {
25912                    }
25913                    mProfilerInfo.profileFd = null;
25914
25915                    if (proc.pid == MY_PID) {
25916                        // When profiling the system server itself, avoid closing the file
25917                        // descriptor, as profilerControl will not create a copy.
25918                        // Note: it is also not correct to just set profileFd to null, as the
25919                        //       whole ProfilerInfo instance is passed down!
25920                        profilerInfo = null;
25921                    }
25922                } else {
25923                    stopProfilerLocked(proc, profileType);
25924                    if (profilerInfo != null && profilerInfo.profileFd != null) {
25925                        try {
25926                            profilerInfo.profileFd.close();
25927                        } catch (IOException e) {
25928                        }
25929                    }
25930                }
25931
25932                return true;
25933            }
25934        } catch (RemoteException e) {
25935            throw new IllegalStateException("Process disappeared");
25936        } finally {
25937            if (profilerInfo != null && profilerInfo.profileFd != null) {
25938                try {
25939                    profilerInfo.profileFd.close();
25940                } catch (IOException e) {
25941                }
25942            }
25943        }
25944    }
25945
25946    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
25947        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
25948                userId, true, ALLOW_FULL_ONLY, callName, null);
25949        ProcessRecord proc = null;
25950        try {
25951            int pid = Integer.parseInt(process);
25952            synchronized (mPidsSelfLocked) {
25953                proc = mPidsSelfLocked.get(pid);
25954            }
25955        } catch (NumberFormatException e) {
25956        }
25957
25958        if (proc == null) {
25959            ArrayMap<String, SparseArray<ProcessRecord>> all
25960                    = mProcessNames.getMap();
25961            SparseArray<ProcessRecord> procs = all.get(process);
25962            if (procs != null && procs.size() > 0) {
25963                proc = procs.valueAt(0);
25964                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
25965                    for (int i=1; i<procs.size(); i++) {
25966                        ProcessRecord thisProc = procs.valueAt(i);
25967                        if (thisProc.userId == userId) {
25968                            proc = thisProc;
25969                            break;
25970                        }
25971                    }
25972                }
25973            }
25974        }
25975
25976        return proc;
25977    }
25978
25979    public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
25980            boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
25981
25982        try {
25983            synchronized (this) {
25984                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
25985                // its own permission (same as profileControl).
25986                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25987                        != PackageManager.PERMISSION_GRANTED) {
25988                    throw new SecurityException("Requires permission "
25989                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25990                }
25991
25992                if (fd == null) {
25993                    throw new IllegalArgumentException("null fd");
25994                }
25995
25996                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
25997                if (proc == null || proc.thread == null) {
25998                    throw new IllegalArgumentException("Unknown process: " + process);
25999                }
26000
26001                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26002                if (!isDebuggable) {
26003                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26004                        throw new SecurityException("Process not debuggable: " + proc);
26005                    }
26006                }
26007
26008                proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
26009                fd = null;
26010                return true;
26011            }
26012        } catch (RemoteException e) {
26013            throw new IllegalStateException("Process disappeared");
26014        } finally {
26015            if (fd != null) {
26016                try {
26017                    fd.close();
26018                } catch (IOException e) {
26019                }
26020            }
26021        }
26022    }
26023
26024    @Override
26025    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
26026            String reportPackage) {
26027        if (processName != null) {
26028            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
26029                    "setDumpHeapDebugLimit()");
26030        } else {
26031            synchronized (mPidsSelfLocked) {
26032                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
26033                if (proc == null) {
26034                    throw new SecurityException("No process found for calling pid "
26035                            + Binder.getCallingPid());
26036                }
26037                if (!Build.IS_DEBUGGABLE
26038                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26039                    throw new SecurityException("Not running a debuggable build");
26040                }
26041                processName = proc.processName;
26042                uid = proc.uid;
26043                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
26044                    throw new SecurityException("Package " + reportPackage + " is not running in "
26045                            + proc);
26046                }
26047            }
26048        }
26049        synchronized (this) {
26050            if (maxMemSize > 0) {
26051                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
26052            } else {
26053                if (uid != 0) {
26054                    mMemWatchProcesses.remove(processName, uid);
26055                } else {
26056                    mMemWatchProcesses.getMap().remove(processName);
26057                }
26058            }
26059        }
26060    }
26061
26062    @Override
26063    public void dumpHeapFinished(String path) {
26064        synchronized (this) {
26065            if (Binder.getCallingPid() != mMemWatchDumpPid) {
26066                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
26067                        + " does not match last pid " + mMemWatchDumpPid);
26068                return;
26069            }
26070            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
26071                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
26072                        + " does not match last path " + mMemWatchDumpFile);
26073                return;
26074            }
26075            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
26076            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
26077
26078            // Forced gc to clean up the remnant hprof fd.
26079            Runtime.getRuntime().gc();
26080        }
26081    }
26082
26083    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
26084    public void monitor() {
26085        synchronized (this) { }
26086    }
26087
26088    void onCoreSettingsChange(Bundle settings) {
26089        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
26090            ProcessRecord processRecord = mLruProcesses.get(i);
26091            try {
26092                if (processRecord.thread != null) {
26093                    processRecord.thread.setCoreSettings(settings);
26094                }
26095            } catch (RemoteException re) {
26096                /* ignore */
26097            }
26098        }
26099    }
26100
26101    // Multi-user methods
26102
26103    /**
26104     * Start user, if its not already running, but don't bring it to foreground.
26105     */
26106    @Override
26107    public boolean startUserInBackground(final int userId) {
26108        return startUserInBackgroundWithListener(userId, null);
26109    }
26110
26111    @Override
26112    public boolean startUserInBackgroundWithListener(final int userId,
26113                @Nullable IProgressListener unlockListener) {
26114        return mUserController.startUser(userId, /* foreground */ false, unlockListener);
26115    }
26116
26117    @Override
26118    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
26119        return mUserController.unlockUser(userId, token, secret, listener);
26120    }
26121
26122    @Override
26123    public boolean switchUser(final int targetUserId) {
26124        return mUserController.switchUser(targetUserId);
26125    }
26126
26127    @Override
26128    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
26129        return mUserController.stopUser(userId, force, callback);
26130    }
26131
26132    @Override
26133    public UserInfo getCurrentUser() {
26134        return mUserController.getCurrentUser();
26135    }
26136
26137    String getStartedUserState(int userId) {
26138        final UserState userState = mUserController.getStartedUserState(userId);
26139        return UserState.stateToString(userState.state);
26140    }
26141
26142    @Override
26143    public boolean isUserRunning(int userId, int flags) {
26144        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
26145                && checkCallingPermission(INTERACT_ACROSS_USERS)
26146                    != PackageManager.PERMISSION_GRANTED) {
26147            String msg = "Permission Denial: isUserRunning() from pid="
26148                    + Binder.getCallingPid()
26149                    + ", uid=" + Binder.getCallingUid()
26150                    + " requires " + INTERACT_ACROSS_USERS;
26151            Slog.w(TAG, msg);
26152            throw new SecurityException(msg);
26153        }
26154        return mUserController.isUserRunning(userId, flags);
26155    }
26156
26157    @Override
26158    public int[] getRunningUserIds() {
26159        if (checkCallingPermission(INTERACT_ACROSS_USERS)
26160                != PackageManager.PERMISSION_GRANTED) {
26161            String msg = "Permission Denial: isUserRunning() from pid="
26162                    + Binder.getCallingPid()
26163                    + ", uid=" + Binder.getCallingUid()
26164                    + " requires " + INTERACT_ACROSS_USERS;
26165            Slog.w(TAG, msg);
26166            throw new SecurityException(msg);
26167        }
26168        return mUserController.getStartedUserArray();
26169    }
26170
26171    @Override
26172    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
26173        mUserController.registerUserSwitchObserver(observer, name);
26174    }
26175
26176    @Override
26177    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
26178        mUserController.unregisterUserSwitchObserver(observer);
26179    }
26180
26181    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
26182        if (info == null) return null;
26183        ApplicationInfo newInfo = new ApplicationInfo(info);
26184        newInfo.initForUser(userId);
26185        return newInfo;
26186    }
26187
26188    public boolean isUserStopped(int userId) {
26189        return mUserController.getStartedUserState(userId) == null;
26190    }
26191
26192    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
26193        if (aInfo == null
26194                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
26195            return aInfo;
26196        }
26197
26198        ActivityInfo info = new ActivityInfo(aInfo);
26199        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
26200        return info;
26201    }
26202
26203    private boolean processSanityChecksLocked(ProcessRecord process) {
26204        if (process == null || process.thread == null) {
26205            return false;
26206        }
26207
26208        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26209        if (!isDebuggable) {
26210            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26211                return false;
26212            }
26213        }
26214
26215        return true;
26216    }
26217
26218    public boolean startBinderTracking() throws RemoteException {
26219        synchronized (this) {
26220            mBinderTransactionTrackingEnabled = true;
26221            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
26222            // permission (same as profileControl).
26223            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26224                    != PackageManager.PERMISSION_GRANTED) {
26225                throw new SecurityException("Requires permission "
26226                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26227            }
26228
26229            for (int i = 0; i < mLruProcesses.size(); i++) {
26230                ProcessRecord process = mLruProcesses.get(i);
26231                if (!processSanityChecksLocked(process)) {
26232                    continue;
26233                }
26234                try {
26235                    process.thread.startBinderTracking();
26236                } catch (RemoteException e) {
26237                    Log.v(TAG, "Process disappared");
26238                }
26239            }
26240            return true;
26241        }
26242    }
26243
26244    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
26245        try {
26246            synchronized (this) {
26247                mBinderTransactionTrackingEnabled = false;
26248                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
26249                // permission (same as profileControl).
26250                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
26251                        != PackageManager.PERMISSION_GRANTED) {
26252                    throw new SecurityException("Requires permission "
26253                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
26254                }
26255
26256                if (fd == null) {
26257                    throw new IllegalArgumentException("null fd");
26258                }
26259
26260                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
26261                pw.println("Binder transaction traces for all processes.\n");
26262                for (ProcessRecord process : mLruProcesses) {
26263                    if (!processSanityChecksLocked(process)) {
26264                        continue;
26265                    }
26266
26267                    pw.println("Traces for process: " + process.processName);
26268                    pw.flush();
26269                    try {
26270                        TransferPipe tp = new TransferPipe();
26271                        try {
26272                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
26273                            tp.go(fd.getFileDescriptor());
26274                        } finally {
26275                            tp.kill();
26276                        }
26277                    } catch (IOException e) {
26278                        pw.println("Failure while dumping IPC traces from " + process +
26279                                ".  Exception: " + e);
26280                        pw.flush();
26281                    } catch (RemoteException e) {
26282                        pw.println("Got a RemoteException while dumping IPC traces from " +
26283                                process + ".  Exception: " + e);
26284                        pw.flush();
26285                    }
26286                }
26287                fd = null;
26288                return true;
26289            }
26290        } finally {
26291            if (fd != null) {
26292                try {
26293                    fd.close();
26294                } catch (IOException e) {
26295                }
26296            }
26297        }
26298    }
26299
26300    @VisibleForTesting
26301    final class LocalService extends ActivityManagerInternal {
26302        @Override
26303        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
26304                int targetUserId) {
26305            synchronized (ActivityManagerService.this) {
26306                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
26307                        targetPkg, intent, null, targetUserId);
26308            }
26309        }
26310
26311        @Override
26312        public String checkContentProviderAccess(String authority, int userId) {
26313            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
26314        }
26315
26316        @Override
26317        public void onWakefulnessChanged(int wakefulness) {
26318            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
26319        }
26320
26321        @Override
26322        public boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
26323                String processName, String abiOverride, int uid, Runnable crashHandler) {
26324            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
26325                    processName, abiOverride, uid, crashHandler);
26326        }
26327
26328        @Override
26329        public SleepToken acquireSleepToken(String tag, int displayId) {
26330            Preconditions.checkNotNull(tag);
26331            return ActivityManagerService.this.acquireSleepToken(tag, displayId);
26332        }
26333
26334        @Override
26335        public ComponentName getHomeActivityForUser(int userId) {
26336            synchronized (ActivityManagerService.this) {
26337                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
26338                return homeActivity == null ? null : homeActivity.realActivity;
26339            }
26340        }
26341
26342        @Override
26343        public void onUserRemoved(int userId) {
26344            synchronized (ActivityManagerService.this) {
26345                ActivityManagerService.this.onUserStoppedLocked(userId);
26346            }
26347            mBatteryStatsService.onUserRemoved(userId);
26348            mUserController.onUserRemoved(userId);
26349        }
26350
26351        @Override
26352        public void onLocalVoiceInteractionStarted(IBinder activity,
26353                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
26354            synchronized (ActivityManagerService.this) {
26355                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
26356                        voiceSession, voiceInteractor);
26357            }
26358        }
26359
26360        @Override
26361        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
26362            synchronized (ActivityManagerService.this) {
26363                mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
26364                        reasons, timestamp);
26365            }
26366        }
26367
26368        @Override
26369        public void notifyAppTransitionFinished() {
26370            synchronized (ActivityManagerService.this) {
26371                mStackSupervisor.notifyAppTransitionDone();
26372            }
26373        }
26374
26375        @Override
26376        public void notifyAppTransitionCancelled() {
26377            synchronized (ActivityManagerService.this) {
26378                mStackSupervisor.notifyAppTransitionDone();
26379            }
26380        }
26381
26382        @Override
26383        public List<IBinder> getTopVisibleActivities() {
26384            synchronized (ActivityManagerService.this) {
26385                return mStackSupervisor.getTopVisibleActivities();
26386            }
26387        }
26388
26389        @Override
26390        public void notifyDockedStackMinimizedChanged(boolean minimized) {
26391            synchronized (ActivityManagerService.this) {
26392                mStackSupervisor.setDockedStackMinimized(minimized);
26393            }
26394        }
26395
26396        @Override
26397        public void killForegroundAppsForUser(int userHandle) {
26398            synchronized (ActivityManagerService.this) {
26399                final ArrayList<ProcessRecord> procs = new ArrayList<>();
26400                final int NP = mProcessNames.getMap().size();
26401                for (int ip = 0; ip < NP; ip++) {
26402                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
26403                    final int NA = apps.size();
26404                    for (int ia = 0; ia < NA; ia++) {
26405                        final ProcessRecord app = apps.valueAt(ia);
26406                        if (app.persistent) {
26407                            // We don't kill persistent processes.
26408                            continue;
26409                        }
26410                        if (app.removed) {
26411                            procs.add(app);
26412                        } else if (app.userId == userHandle && app.foregroundActivities) {
26413                            app.removed = true;
26414                            procs.add(app);
26415                        }
26416                    }
26417                }
26418
26419                final int N = procs.size();
26420                for (int i = 0; i < N; i++) {
26421                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
26422                }
26423            }
26424        }
26425
26426        @Override
26427        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
26428                long duration) {
26429            if (!(target instanceof PendingIntentRecord)) {
26430                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
26431                return;
26432            }
26433            synchronized (ActivityManagerService.this) {
26434                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
26435            }
26436        }
26437
26438        @Override
26439        public void setDeviceIdleWhitelist(int[] allAppids, int[] exceptIdleAppids) {
26440            synchronized (ActivityManagerService.this) {
26441                mDeviceIdleWhitelist = allAppids;
26442                mDeviceIdleExceptIdleWhitelist = exceptIdleAppids;
26443            }
26444        }
26445
26446        @Override
26447        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
26448            synchronized (ActivityManagerService.this) {
26449                mDeviceIdleTempWhitelist = appids;
26450                setAppIdTempWhitelistStateLocked(changingAppId, adding);
26451            }
26452        }
26453
26454        @Override
26455        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
26456                int userId) {
26457            Preconditions.checkNotNull(values, "Configuration must not be null");
26458            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
26459            synchronized (ActivityManagerService.this) {
26460                updateConfigurationLocked(values, null, false, true, userId,
26461                        false /* deferResume */);
26462            }
26463        }
26464
26465        @Override
26466        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
26467                Bundle bOptions) {
26468            Preconditions.checkNotNull(intents, "intents");
26469            final String[] resolvedTypes = new String[intents.length];
26470
26471            // UID of the package on user userId.
26472            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
26473            // packageUid may not be initialized.
26474            int packageUid = 0;
26475            final long ident = Binder.clearCallingIdentity();
26476
26477            try {
26478                for (int i = 0; i < intents.length; i++) {
26479                    resolvedTypes[i] =
26480                            intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
26481                }
26482
26483                packageUid = AppGlobals.getPackageManager().getPackageUid(
26484                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
26485            } catch (RemoteException e) {
26486                // Shouldn't happen.
26487            } finally {
26488                Binder.restoreCallingIdentity(ident);
26489            }
26490
26491            synchronized (ActivityManagerService.this) {
26492                return mActivityStartController.startActivitiesInPackage(
26493                        packageUid, packageName,
26494                        intents, resolvedTypes, null /* resultTo */,
26495                        SafeActivityOptions.fromBundle(bOptions), userId,
26496                        false /* validateIncomingUser */);
26497            }
26498        }
26499
26500        @Override
26501        public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
26502                Intent intent, Bundle options, int userId) {
26503            return ActivityManagerService.this.startActivityAsUser(
26504                    caller, callerPacakge, intent,
26505                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
26506                    null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
26507                    false /*validateIncomingUser*/);
26508        }
26509
26510        @Override
26511        public int getUidProcessState(int uid) {
26512            return getUidState(uid);
26513        }
26514
26515        @Override
26516        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
26517            synchronized (ActivityManagerService.this) {
26518
26519                // We might change the visibilities here, so prepare an empty app transition which
26520                // might be overridden later if we actually change visibilities.
26521                final boolean wasTransitionSet =
26522                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
26523                if (!wasTransitionSet) {
26524                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
26525                            false /* alwaysKeepCurrent */);
26526                }
26527                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
26528
26529                // If there was a transition set already we don't want to interfere with it as we
26530                // might be starting it too early.
26531                if (!wasTransitionSet) {
26532                    mWindowManager.executeAppTransition();
26533                }
26534            }
26535            if (callback != null) {
26536                callback.run();
26537            }
26538        }
26539
26540        @Override
26541        public boolean isSystemReady() {
26542            // no need to synchronize(this) just to read & return the value
26543            return mSystemReady;
26544        }
26545
26546        @Override
26547        public void notifyKeyguardTrustedChanged() {
26548            synchronized (ActivityManagerService.this) {
26549                if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
26550                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
26551                }
26552            }
26553        }
26554
26555        /**
26556         * Sets if the given pid has an overlay UI or not.
26557         *
26558         * @param pid The pid we are setting overlay UI for.
26559         * @param hasOverlayUi True if the process has overlay UI.
26560         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
26561         */
26562        @Override
26563        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
26564            synchronized (ActivityManagerService.this) {
26565                final ProcessRecord pr;
26566                synchronized (mPidsSelfLocked) {
26567                    pr = mPidsSelfLocked.get(pid);
26568                    if (pr == null) {
26569                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
26570                        return;
26571                    }
26572                }
26573                if (pr.hasOverlayUi == hasOverlayUi) {
26574                    return;
26575                }
26576                pr.hasOverlayUi = hasOverlayUi;
26577                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
26578                updateOomAdjLocked(pr, true);
26579            }
26580        }
26581
26582        @Override
26583        public void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
26584            ActivityManagerService.this.setRunningRemoteAnimation(pid, runningRemoteAnimation);
26585        }
26586
26587        /**
26588         * Called after the network policy rules are updated by
26589         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
26590         * and {@param procStateSeq}.
26591         */
26592        @Override
26593        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
26594            if (DEBUG_NETWORK) {
26595                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
26596                        + uid + " seq: " + procStateSeq);
26597            }
26598            UidRecord record;
26599            synchronized (ActivityManagerService.this) {
26600                record = mActiveUids.get(uid);
26601                if (record == null) {
26602                    if (DEBUG_NETWORK) {
26603                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
26604                                + " procStateSeq: " + procStateSeq);
26605                    }
26606                    return;
26607                }
26608            }
26609            synchronized (record.networkStateLock) {
26610                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
26611                    if (DEBUG_NETWORK) {
26612                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
26613                                + " been handled for uid: " + uid);
26614                    }
26615                    return;
26616                }
26617                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
26618                if (record.curProcStateSeq > procStateSeq) {
26619                    if (DEBUG_NETWORK) {
26620                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
26621                                + ", curProcstateSeq: " + record.curProcStateSeq
26622                                + ", procStateSeq: " + procStateSeq);
26623                    }
26624                    return;
26625                }
26626                if (record.waitingForNetwork) {
26627                    if (DEBUG_NETWORK) {
26628                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
26629                                + ", procStateSeq: " + procStateSeq);
26630                    }
26631                    record.networkStateLock.notifyAll();
26632                }
26633            }
26634        }
26635
26636        @Override
26637        public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
26638            synchronized (ActivityManagerService.this) {
26639                mActiveVoiceInteractionServiceComponent = component;
26640            }
26641        }
26642
26643        /**
26644         * Called after virtual display Id is updated by
26645         * {@link com.android.server.vr.Vr2dDisplay} with a specific
26646         * {@param vrVr2dDisplayId}.
26647         */
26648        @Override
26649        public void setVr2dDisplayId(int vr2dDisplayId) {
26650            if (DEBUG_STACK) {
26651                Slog.d(TAG, "setVr2dDisplayId called for: " +
26652                        vr2dDisplayId);
26653            }
26654            synchronized (ActivityManagerService.this) {
26655                mVr2dDisplayId = vr2dDisplayId;
26656            }
26657        }
26658
26659        @Override
26660        public void saveANRState(String reason) {
26661            synchronized (ActivityManagerService.this) {
26662                final StringWriter sw = new StringWriter();
26663                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
26664                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
26665                if (reason != null) {
26666                    pw.println("  Reason: " + reason);
26667                }
26668                pw.println();
26669                mActivityStartController.dump(pw, "  ", null);
26670                pw.println();
26671                pw.println("-------------------------------------------------------------------------------");
26672                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
26673                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
26674                        "" /* header */);
26675                pw.println();
26676                pw.close();
26677
26678                mLastANRState = sw.toString();
26679            }
26680        }
26681
26682        @Override
26683        public void clearSavedANRState() {
26684            synchronized (ActivityManagerService.this) {
26685                mLastANRState = null;
26686            }
26687        }
26688
26689        @Override
26690        public void setFocusedActivity(IBinder token) {
26691            synchronized (ActivityManagerService.this) {
26692                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
26693                if (r == null) {
26694                    throw new IllegalArgumentException(
26695                            "setFocusedActivity: No activity record matching token=" + token);
26696                }
26697                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
26698                        r, "setFocusedActivity")) {
26699                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
26700                }
26701            }
26702        }
26703
26704        @Override
26705        public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
26706            synchronized (ActivityManagerService.this) {
26707                if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
26708                    ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
26709                    if (types == null) {
26710                        if (uid < 0) {
26711                            return;
26712                        }
26713                        types = new ArrayMap<>();
26714                        mAllowAppSwitchUids.put(userId, types);
26715                    }
26716                    if (uid < 0) {
26717                        types.remove(type);
26718                    } else {
26719                        types.put(type, uid);
26720                    }
26721                }
26722            }
26723        }
26724
26725        @Override
26726        public boolean isRuntimeRestarted() {
26727            return mSystemServiceManager.isRuntimeRestarted();
26728        }
26729
26730        @Override
26731        public boolean hasRunningActivity(int uid, @Nullable String packageName) {
26732            if (packageName == null) return false;
26733
26734            synchronized (ActivityManagerService.this) {
26735                for (int i = 0; i < mLruProcesses.size(); i++) {
26736                    final ProcessRecord processRecord = mLruProcesses.get(i);
26737                    if (processRecord.uid == uid) {
26738                        for (int j = 0; j < processRecord.activities.size(); j++) {
26739                            final ActivityRecord activityRecord = processRecord.activities.get(j);
26740                            if (packageName.equals(activityRecord.packageName)) {
26741                                return true;
26742                            }
26743                        }
26744                    }
26745                }
26746            }
26747            return false;
26748        }
26749
26750        @Override
26751        public void registerScreenObserver(ScreenObserver observer) {
26752            mScreenObservers.add(observer);
26753        }
26754
26755        @Override
26756        public boolean canStartMoreUsers() {
26757            return mUserController.canStartMoreUsers();
26758        }
26759
26760        @Override
26761        public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
26762            mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage);
26763        }
26764
26765        @Override
26766        public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
26767            mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage);
26768        }
26769
26770        @Override
26771        public int getMaxRunningUsers() {
26772            return mUserController.mMaxRunningUsers;
26773        }
26774
26775        @Override
26776        public boolean isCallerRecents(int callingUid) {
26777            return getRecentTasks().isCallerRecents(callingUid);
26778        }
26779
26780        @Override
26781        public boolean isRecentsComponentHomeActivity(int userId) {
26782            return getRecentTasks().isRecentsComponentHomeActivity(userId);
26783        }
26784
26785        @Override
26786        public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
26787            ActivityManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
26788        }
26789
26790        @Override
26791        public boolean isUidActive(int uid) {
26792            synchronized (ActivityManagerService.this) {
26793                return isUidActiveLocked(uid);
26794            }
26795        }
26796
26797        @Override
26798        public List<ProcessMemoryState> getMemoryStateForProcesses() {
26799            List<ProcessMemoryState> processMemoryStates = new ArrayList<>();
26800            synchronized (mPidsSelfLocked) {
26801                for (int i = 0, size = mPidsSelfLocked.size(); i < size; i++) {
26802                    final ProcessRecord r = mPidsSelfLocked.valueAt(i);
26803                    final int pid = r.pid;
26804                    final int uid = r.uid;
26805                    final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
26806                    if (memoryStat == null) {
26807                        continue;
26808                    }
26809                    ProcessMemoryState processMemoryState =
26810                            new ProcessMemoryState(uid,
26811                                    r.processName,
26812                                    r.maxAdj,
26813                                    memoryStat.pgfault,
26814                                    memoryStat.pgmajfault,
26815                                    memoryStat.rssInBytes,
26816                                    memoryStat.cacheInBytes,
26817                                    memoryStat.swapInBytes);
26818                    processMemoryStates.add(processMemoryState);
26819                }
26820            }
26821            return processMemoryStates;
26822        }
26823
26824        @Override
26825        public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
26826            ActivityManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
26827        }
26828    }
26829
26830    /**
26831     * Called by app main thread to wait for the network policy rules to get updated.
26832     *
26833     * @param procStateSeq The sequence number indicating the process state change that the main
26834     *                     thread is interested in.
26835     */
26836    @Override
26837    public void waitForNetworkStateUpdate(long procStateSeq) {
26838        final int callingUid = Binder.getCallingUid();
26839        if (DEBUG_NETWORK) {
26840            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
26841        }
26842        UidRecord record;
26843        synchronized (this) {
26844            record = mActiveUids.get(callingUid);
26845            if (record == null) {
26846                return;
26847            }
26848        }
26849        synchronized (record.networkStateLock) {
26850            if (record.lastDispatchedProcStateSeq < procStateSeq) {
26851                if (DEBUG_NETWORK) {
26852                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
26853                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
26854                            + " lastProcStateSeqDispatchedToObservers: "
26855                            + record.lastDispatchedProcStateSeq);
26856                }
26857                return;
26858            }
26859            if (record.curProcStateSeq > procStateSeq) {
26860                if (DEBUG_NETWORK) {
26861                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
26862                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
26863                            + ", procStateSeq: " + procStateSeq);
26864                }
26865                return;
26866            }
26867            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
26868                if (DEBUG_NETWORK) {
26869                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
26870                            + procStateSeq + ", so no need to wait. Uid: "
26871                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
26872                            + record.lastNetworkUpdatedProcStateSeq);
26873                }
26874                return;
26875            }
26876            try {
26877                if (DEBUG_NETWORK) {
26878                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
26879                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
26880                }
26881                final long startTime = SystemClock.uptimeMillis();
26882                record.waitingForNetwork = true;
26883                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
26884                record.waitingForNetwork = false;
26885                final long totalTime = SystemClock.uptimeMillis() - startTime;
26886                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
26887                    Slog.w(TAG_NETWORK, "Total time waited for network rules to get updated: "
26888                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
26889                            + procStateSeq + " UidRec: " + record
26890                            + " validateUidRec: " + mValidateUids.get(callingUid));
26891                }
26892            } catch (InterruptedException e) {
26893                Thread.currentThread().interrupt();
26894            }
26895        }
26896    }
26897
26898    public void waitForBroadcastIdle(PrintWriter pw) {
26899        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
26900        while (true) {
26901            boolean idle = true;
26902            synchronized (this) {
26903                for (BroadcastQueue queue : mBroadcastQueues) {
26904                    if (!queue.isIdle()) {
26905                        final String msg = "Waiting for queue " + queue + " to become idle...";
26906                        pw.println(msg);
26907                        pw.flush();
26908                        Slog.v(TAG, msg);
26909                        idle = false;
26910                    }
26911                }
26912            }
26913
26914            if (idle) {
26915                final String msg = "All broadcast queues are idle!";
26916                pw.println(msg);
26917                pw.flush();
26918                Slog.v(TAG, msg);
26919                return;
26920            } else {
26921                SystemClock.sleep(1000);
26922            }
26923        }
26924    }
26925
26926    /**
26927     * Return the user id of the last resumed activity.
26928     */
26929    @Override
26930    public @UserIdInt int getLastResumedActivityUserId() {
26931        enforceCallingPermission(
26932                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
26933        synchronized (this) {
26934            if (mLastResumedActivity == null) {
26935                return mUserController.getCurrentUserId();
26936            }
26937            return mLastResumedActivity.userId;
26938        }
26939    }
26940
26941    /**
26942     * Kill processes for the user with id userId and that depend on the package named packageName
26943     */
26944    @Override
26945    public void killPackageDependents(String packageName, int userId) {
26946        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
26947        if (packageName == null) {
26948            throw new NullPointerException(
26949                    "Cannot kill the dependents of a package without its name.");
26950        }
26951
26952        long callingId = Binder.clearCallingIdentity();
26953        IPackageManager pm = AppGlobals.getPackageManager();
26954        int pkgUid = -1;
26955        try {
26956            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
26957        } catch (RemoteException e) {
26958        }
26959        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
26960            throw new IllegalArgumentException(
26961                    "Cannot kill dependents of non-existing package " + packageName);
26962        }
26963        try {
26964            synchronized(this) {
26965                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
26966                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
26967                        "dep: " + packageName);
26968            }
26969        } finally {
26970            Binder.restoreCallingIdentity(callingId);
26971        }
26972    }
26973
26974    @Override
26975    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
26976            CharSequence message) throws RemoteException {
26977        if (message != null) {
26978            enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
26979                    "dismissKeyguard()");
26980        }
26981        final long callingId = Binder.clearCallingIdentity();
26982        try {
26983            mKeyguardController.dismissKeyguard(token, callback, message);
26984        } finally {
26985            Binder.restoreCallingIdentity(callingId);
26986        }
26987    }
26988
26989    @Override
26990    public int restartUserInBackground(final int userId) {
26991        return mUserController.restartUser(userId, /* foreground */ false);
26992    }
26993
26994    @Override
26995    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
26996        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
26997                "scheduleApplicationInfoChanged()");
26998
26999        synchronized (this) {
27000            final long origId = Binder.clearCallingIdentity();
27001            try {
27002                updateApplicationInfoLocked(packageNames, userId);
27003            } finally {
27004                Binder.restoreCallingIdentity(origId);
27005            }
27006        }
27007    }
27008
27009    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
27010        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
27011        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
27012            final ProcessRecord app = mLruProcesses.get(i);
27013            if (app.thread == null) {
27014                continue;
27015            }
27016
27017            if (userId != UserHandle.USER_ALL && app.userId != userId) {
27018                continue;
27019            }
27020
27021            final int packageCount = app.pkgList.size();
27022            for (int j = 0; j < packageCount; j++) {
27023                final String packageName = app.pkgList.keyAt(j);
27024                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
27025                    try {
27026                        final ApplicationInfo ai = AppGlobals.getPackageManager()
27027                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
27028                        if (ai != null) {
27029                            app.thread.scheduleApplicationInfoChanged(ai);
27030                        }
27031                    } catch (RemoteException e) {
27032                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
27033                                    packageName, app));
27034                    }
27035                }
27036            }
27037        }
27038        if (updateFrameworkRes) {
27039            // Update system server components that need to know about changed overlays. Because the
27040            // overlay is applied in ActivityThread, we need to serialize through its thread too.
27041            final Executor executor = ActivityThread.currentActivityThread().getExecutor();
27042            final DisplayManagerInternal display =
27043                    LocalServices.getService(DisplayManagerInternal.class);
27044            if (display != null) {
27045                executor.execute(display::onOverlayChanged);
27046            }
27047            if (mWindowManager != null) {
27048                executor.execute(mWindowManager::onOverlayChanged);
27049            }
27050        }
27051    }
27052
27053    /**
27054     * Attach an agent to the specified process (proces name or PID)
27055     */
27056    public void attachAgent(String process, String path) {
27057        try {
27058            synchronized (this) {
27059                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
27060                if (proc == null || proc.thread == null) {
27061                    throw new IllegalArgumentException("Unknown process: " + process);
27062                }
27063
27064                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
27065                if (!isDebuggable) {
27066                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
27067                        throw new SecurityException("Process not debuggable: " + proc);
27068                    }
27069                }
27070
27071                proc.thread.attachAgent(path);
27072            }
27073        } catch (RemoteException e) {
27074            throw new IllegalStateException("Process disappeared");
27075        }
27076    }
27077
27078    @VisibleForTesting
27079    public static class Injector {
27080        private NetworkManagementInternal mNmi;
27081
27082        public Context getContext() {
27083            return null;
27084        }
27085
27086        public AppOpsService getAppOpsService(File file, Handler handler) {
27087            return new AppOpsService(file, handler);
27088        }
27089
27090        public Handler getUiHandler(ActivityManagerService service) {
27091            return service.new UiHandler();
27092        }
27093
27094        public boolean isNetworkRestrictedForUid(int uid) {
27095            if (ensureHasNetworkManagementInternal()) {
27096                return mNmi.isNetworkRestrictedForUid(uid);
27097            }
27098            return false;
27099        }
27100
27101        private boolean ensureHasNetworkManagementInternal() {
27102            if (mNmi == null) {
27103                mNmi = LocalServices.getService(NetworkManagementInternal.class);
27104            }
27105            return mNmi != null;
27106        }
27107    }
27108
27109    @Override
27110    public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
27111            throws RemoteException {
27112        synchronized (this) {
27113            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27114            if (r == null) {
27115                return;
27116            }
27117            final long origId = Binder.clearCallingIdentity();
27118            try {
27119                r.setShowWhenLocked(showWhenLocked);
27120            } finally {
27121                Binder.restoreCallingIdentity(origId);
27122            }
27123        }
27124    }
27125
27126    @Override
27127    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
27128        synchronized (this) {
27129            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27130            if (r == null) {
27131                return;
27132            }
27133            final long origId = Binder.clearCallingIdentity();
27134            try {
27135                r.setTurnScreenOn(turnScreenOn);
27136            } finally {
27137                Binder.restoreCallingIdentity(origId);
27138            }
27139        }
27140    }
27141
27142    @Override
27143    public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)
27144            throws RemoteException {
27145        enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
27146                "registerRemoteAnimations");
27147        definition.setCallingPid(Binder.getCallingPid());
27148        synchronized (this) {
27149            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
27150            if (r == null) {
27151                return;
27152            }
27153            final long origId = Binder.clearCallingIdentity();
27154            try {
27155                r.registerRemoteAnimations(definition);
27156            } finally {
27157                Binder.restoreCallingIdentity(origId);
27158            }
27159        }
27160    }
27161
27162    @Override
27163    public void registerRemoteAnimationForNextActivityStart(String packageName,
27164            RemoteAnimationAdapter adapter) throws RemoteException {
27165        enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
27166                "registerRemoteAnimationForNextActivityStart");
27167        adapter.setCallingPid(Binder.getCallingPid());
27168        synchronized (this) {
27169            final long origId = Binder.clearCallingIdentity();
27170            try {
27171                mActivityStartController.registerRemoteAnimationForNextActivityStart(packageName,
27172                        adapter);
27173            } finally {
27174                Binder.restoreCallingIdentity(origId);
27175            }
27176        }
27177    }
27178
27179    /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
27180    @Override
27181    public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
27182        synchronized (this) {
27183            final long origId = Binder.clearCallingIdentity();
27184            try {
27185                mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
27186            } finally {
27187                Binder.restoreCallingIdentity(origId);
27188            }
27189        }
27190    }
27191}
27192