ActivityManagerService.java revision c7933acad1e6a66f7858bc92b057f6fd6d72c803
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.app.ActivityManager.LOCK_TASK_MODE_NONE;
31import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
32import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
33import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
34import static android.app.ActivityManagerInternal.ASSIST_KEY_CONTENT;
35import static android.app.ActivityManagerInternal.ASSIST_KEY_DATA;
36import static android.app.ActivityManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
37import static android.app.ActivityManagerInternal.ASSIST_KEY_STRUCTURE;
38import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
39import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE;
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.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
54import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
55import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
56import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
57import static android.content.pm.PackageManager.GET_PROVIDERS;
58import static android.content.pm.PackageManager.MATCH_ANY_USER;
59import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
60import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
61import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
62import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
63import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
64import static android.content.pm.PackageManager.PERMISSION_GRANTED;
65import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
66import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
67import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
68import static android.os.Build.VERSION_CODES.N;
69import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
70import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
71import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
72import static android.os.IServiceManager.DUMP_FLAG_PROTO;
73import static android.os.Process.BLUETOOTH_UID;
74import static android.os.Process.FIRST_APPLICATION_UID;
75import static android.os.Process.FIRST_ISOLATED_UID;
76import static android.os.Process.LAST_ISOLATED_UID;
77import static android.os.Process.NFC_UID;
78import static android.os.Process.PHONE_UID;
79import static android.os.Process.PROC_CHAR;
80import static android.os.Process.PROC_OUT_LONG;
81import static android.os.Process.PROC_PARENS;
82import static android.os.Process.PROC_SPACE_TERM;
83import static android.os.Process.ProcessStartResult;
84import static android.os.Process.ROOT_UID;
85import static android.os.Process.SCHED_FIFO;
86import static android.os.Process.SCHED_OTHER;
87import static android.os.Process.SCHED_RESET_ON_FORK;
88import static android.os.Process.SE_UID;
89import static android.os.Process.SHELL_UID;
90import static android.os.Process.SIGNAL_QUIT;
91import static android.os.Process.SIGNAL_USR1;
92import static android.os.Process.SYSTEM_UID;
93import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
94import static android.os.Process.THREAD_GROUP_DEFAULT;
95import static android.os.Process.THREAD_GROUP_TOP_APP;
96import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
97import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
98import static android.os.Process.getFreeMemory;
99import static android.os.Process.getTotalMemory;
100import static android.os.Process.isThreadInProcess;
101import static android.os.Process.killProcess;
102import static android.os.Process.killProcessQuiet;
103import static android.os.Process.myPid;
104import static android.os.Process.myUid;
105import static android.os.Process.readProcFile;
106import static android.os.Process.removeAllProcessGroups;
107import static android.os.Process.sendSignal;
108import static android.os.Process.setProcessGroup;
109import static android.os.Process.setThreadPriority;
110import static android.os.Process.setThreadScheduler;
111import static android.os.Process.startWebView;
112import static android.os.Process.zygoteProcess;
113import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
114import static android.provider.Settings.Global.DEBUG_APP;
115import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
116import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
117import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
118import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
119import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
120import static android.provider.Settings.System.FONT_SCALE;
121import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
122import static android.text.format.DateUtils.DAY_IN_MILLIS;
123import static android.view.Display.DEFAULT_DISPLAY;
124import static android.view.Display.INVALID_DISPLAY;
125import static com.android.internal.util.XmlUtils.readBooleanAttribute;
126import static com.android.internal.util.XmlUtils.readIntAttribute;
127import static com.android.internal.util.XmlUtils.readLongAttribute;
128import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
129import static com.android.internal.util.XmlUtils.writeIntAttribute;
130import static com.android.internal.util.XmlUtils.writeLongAttribute;
131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
141import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
142import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
143import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
144import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
145import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
146import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
147import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
148import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
149import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
150import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
151import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
152import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
153import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
154import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
155import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
156import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
157import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
158import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
159import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
160import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
161import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
162import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
163import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
164import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
165import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
166import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
167import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
168import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
169import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
170import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
171import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
172import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
173import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
174import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
175import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
176import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
177import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
178import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
179import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
180import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
181import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
182import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
183import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
184import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
185import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
186import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
187import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
188import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
189import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
190import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
191import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
192import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
193import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
194import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
195import static com.android.server.am.MemoryStatUtil.hasMemcg;
196import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
197import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
198import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
199import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
200import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
201import static android.view.WindowManager.TRANSIT_NONE;
202import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
203import static android.view.WindowManager.TRANSIT_TASK_OPEN;
204import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
205import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
206import static org.xmlpull.v1.XmlPullParser.START_TAG;
207
208import android.Manifest;
209import android.Manifest.permission;
210import android.annotation.NonNull;
211import android.annotation.Nullable;
212import android.annotation.UserIdInt;
213import android.app.Activity;
214import android.app.ActivityManager;
215import android.app.ActivityManager.RunningTaskInfo;
216import android.app.ActivityManager.StackInfo;
217import android.app.ActivityManager.TaskSnapshot;
218import android.app.ActivityManagerInternal;
219import android.app.ActivityManagerInternal.ScreenObserver;
220import android.app.ActivityManagerInternal.SleepToken;
221import android.app.ActivityManagerProto;
222import android.app.ActivityOptions;
223import android.app.ActivityThread;
224import android.app.AlertDialog;
225import android.app.AppGlobals;
226import android.app.AppOpsManager;
227import android.app.ApplicationErrorReport;
228import android.app.ApplicationThreadConstants;
229import android.app.BroadcastOptions;
230import android.app.ContentProviderHolder;
231import android.app.Dialog;
232import android.app.GrantedUriPermission;
233import android.app.IActivityController;
234import android.app.IActivityManager;
235import android.app.IApplicationThread;
236import android.app.IAssistDataReceiver;
237import android.app.IInstrumentationWatcher;
238import android.app.INotificationManager;
239import android.app.IProcessObserver;
240import android.app.IServiceConnection;
241import android.app.IStopUserCallback;
242import android.app.ITaskStackListener;
243import android.app.IUiAutomationConnection;
244import android.app.IUidObserver;
245import android.app.IUserSwitchObserver;
246import android.app.Instrumentation;
247import android.app.Notification;
248import android.app.NotificationManager;
249import android.app.PendingIntent;
250import android.app.PictureInPictureParams;
251import android.app.ProcessMemoryState;
252import android.app.ProfilerInfo;
253import android.app.RemoteAction;
254import android.app.WaitResult;
255import android.app.WindowConfiguration.ActivityType;
256import android.app.WindowConfiguration.WindowingMode;
257import android.app.admin.DevicePolicyCache;
258import android.app.admin.DevicePolicyManager;
259import android.app.assist.AssistContent;
260import android.app.assist.AssistStructure;
261import android.app.backup.IBackupManager;
262import android.app.servertransaction.ConfigurationChangeItem;
263import android.app.usage.UsageEvents;
264import android.app.usage.UsageStatsManagerInternal;
265import android.appwidget.AppWidgetManager;
266import android.content.ActivityNotFoundException;
267import android.content.BroadcastReceiver;
268import android.content.ClipData;
269import android.content.ComponentCallbacks2;
270import android.content.ComponentName;
271import android.content.ContentProvider;
272import android.content.ContentResolver;
273import android.content.Context;
274import android.content.DialogInterface;
275import android.content.IContentProvider;
276import android.content.IIntentReceiver;
277import android.content.IIntentSender;
278import android.content.Intent;
279import android.content.IntentFilter;
280import android.content.pm.ActivityInfo;
281import android.content.pm.ApplicationInfo;
282import android.content.pm.ConfigurationInfo;
283import android.content.pm.IPackageDataObserver;
284import android.content.pm.IPackageManager;
285import android.content.pm.InstrumentationInfo;
286import android.content.pm.PackageInfo;
287import android.content.pm.PackageManager;
288import android.content.pm.PackageManager.NameNotFoundException;
289import android.content.pm.PackageManagerInternal;
290import android.content.pm.ParceledListSlice;
291import android.content.pm.PathPermission;
292import android.content.pm.PermissionInfo;
293import android.content.pm.ProviderInfo;
294import android.content.pm.ResolveInfo;
295import android.content.pm.SELinuxUtil;
296import android.content.pm.ServiceInfo;
297import android.content.pm.UserInfo;
298import android.content.res.CompatibilityInfo;
299import android.content.res.Configuration;
300import android.content.res.Resources;
301import android.database.ContentObserver;
302import android.graphics.Bitmap;
303import android.graphics.Point;
304import android.graphics.Rect;
305import android.hardware.display.DisplayManagerInternal;
306import android.location.LocationManager;
307import android.media.audiofx.AudioEffect;
308import android.metrics.LogMaker;
309import android.net.Proxy;
310import android.net.ProxyInfo;
311import android.net.Uri;
312import android.os.BatteryStats;
313import android.os.Binder;
314import android.os.Build;
315import android.os.Bundle;
316import android.os.Debug;
317import android.os.DropBoxManager;
318import android.os.Environment;
319import android.os.FactoryTest;
320import android.os.FileObserver;
321import android.os.FileUtils;
322import android.os.Handler;
323import android.os.IBinder;
324import android.os.IDeviceIdentifiersPolicyService;
325import android.os.IPermissionController;
326import android.os.IProcessInfoService;
327import android.os.IProgressListener;
328import android.os.LocaleList;
329import android.os.Looper;
330import android.os.Message;
331import android.os.Parcel;
332import android.os.ParcelFileDescriptor;
333import android.os.PersistableBundle;
334import android.os.PowerManager;
335import android.os.PowerManager.ServiceType;
336import android.os.PowerManagerInternal;
337import android.os.Process;
338import android.os.RemoteCallbackList;
339import android.os.RemoteException;
340import android.os.ResultReceiver;
341import android.os.ServiceManager;
342import android.os.ShellCallback;
343import android.os.StrictMode;
344import android.os.SystemClock;
345import android.os.SystemProperties;
346import android.os.Trace;
347import android.os.TransactionTooLargeException;
348import android.os.UpdateLock;
349import android.os.UserHandle;
350import android.os.UserManager;
351import android.os.WorkSource;
352import android.os.storage.IStorageManager;
353import android.os.storage.StorageManager;
354import android.os.storage.StorageManagerInternal;
355import android.provider.Downloads;
356import android.provider.Settings;
357import android.service.voice.IVoiceInteractionSession;
358import android.service.voice.VoiceInteractionManagerInternal;
359import android.telecom.TelecomManager;
360import android.text.TextUtils;
361import android.text.format.DateUtils;
362import android.text.format.Time;
363import android.text.style.SuggestionSpan;
364import android.util.ArrayMap;
365import android.util.ArraySet;
366import android.util.AtomicFile;
367import android.util.DebugUtils;
368import android.util.EventLog;
369import android.util.Log;
370import android.util.LongSparseArray;
371import android.util.Pair;
372import android.util.PrintWriterPrinter;
373import android.util.Slog;
374import android.util.SparseArray;
375import android.util.SparseIntArray;
376import android.util.StatsLog;
377import android.util.TimeUtils;
378import android.util.TimingsTraceLog;
379import android.util.Xml;
380import android.util.proto.ProtoOutputStream;
381import android.util.proto.ProtoUtils;
382import android.view.Gravity;
383import android.view.IRecentsAnimationRunner;
384import android.view.LayoutInflater;
385import android.view.RemoteAnimationAdapter;
386import android.view.RemoteAnimationDefinition;
387import android.view.View;
388import android.view.WindowManager;
389import android.view.autofill.AutofillManagerInternal;
390
391import com.android.internal.R;
392import com.android.internal.annotations.GuardedBy;
393import com.android.internal.annotations.VisibleForTesting;
394import com.android.internal.app.AssistUtils;
395import com.android.internal.app.DumpHeapActivity;
396import com.android.internal.app.IAppOpsCallback;
397import com.android.internal.app.IAppOpsService;
398import com.android.internal.app.IVoiceInteractor;
399import com.android.internal.app.ProcessMap;
400import com.android.internal.app.SystemUserHomeActivity;
401import com.android.internal.app.procstats.ProcessStats;
402import com.android.internal.logging.MetricsLogger;
403import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
404import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
405import com.android.internal.notification.SystemNotificationChannels;
406import com.android.internal.os.BackgroundThread;
407import com.android.internal.os.BatteryStatsImpl;
408import com.android.internal.os.BinderInternal;
409import com.android.internal.os.logging.MetricsLoggerWrapper;
410import com.android.internal.os.ByteTransferPipe;
411import com.android.internal.os.IResultReceiver;
412import com.android.internal.os.ProcessCpuTracker;
413import com.android.internal.os.TransferPipe;
414import com.android.internal.os.Zygote;
415import com.android.internal.policy.IKeyguardDismissCallback;
416import com.android.internal.policy.KeyguardDismissCallback;
417import com.android.internal.telephony.TelephonyIntents;
418import com.android.internal.util.ArrayUtils;
419import com.android.internal.util.DumpUtils;
420import com.android.internal.util.FastPrintWriter;
421import com.android.internal.util.FastXmlSerializer;
422import com.android.internal.util.MemInfoReader;
423import com.android.internal.util.Preconditions;
424import com.android.server.AlarmManagerInternal;
425import com.android.server.AppOpsService;
426import com.android.server.AttributeCache;
427import com.android.server.DeviceIdleController;
428import com.android.server.IntentResolver;
429import com.android.server.IoThread;
430import com.android.server.LocalServices;
431import com.android.server.LockGuard;
432import com.android.server.NetworkManagementInternal;
433import com.android.server.RescueParty;
434import com.android.server.ServiceThread;
435import com.android.server.SystemConfig;
436import com.android.server.SystemService;
437import com.android.server.SystemServiceManager;
438import com.android.server.ThreadPriorityBooster;
439import com.android.server.Watchdog;
440import com.android.server.am.ActivityStack.ActivityState;
441import com.android.server.am.MemoryStatUtil.MemoryStat;
442import com.android.server.am.proto.ActivityManagerServiceProto;
443import com.android.server.am.proto.ActivityManagerServiceDumpActivitiesProto;
444import com.android.server.am.proto.ActivityManagerServiceDumpBroadcastsProto;
445import com.android.server.am.proto.ActivityManagerServiceDumpProcessesProto;
446import com.android.server.am.proto.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
447import com.android.server.am.proto.ActivityManagerServiceDumpServicesProto;
448import com.android.server.am.proto.GrantUriProto;
449import com.android.server.am.proto.ImportanceTokenProto;
450import com.android.server.am.proto.MemInfoDumpProto;
451import com.android.server.am.proto.NeededUriGrantsProto;
452import com.android.server.am.proto.ProcessOomProto;
453import com.android.server.am.proto.ProcessToGcProto;
454import com.android.server.am.proto.StickyBroadcastProto;
455import com.android.server.firewall.IntentFirewall;
456import com.android.server.job.JobSchedulerInternal;
457import com.android.server.pm.Installer;
458import com.android.server.pm.Installer.InstallerException;
459import com.android.server.utils.PriorityDump;
460import com.android.server.vr.VrManagerInternal;
461import com.android.server.wm.PinnedStackWindowController;
462import com.android.server.wm.WindowManagerService;
463
464import dalvik.system.VMRuntime;
465
466import libcore.io.IoUtils;
467import libcore.util.EmptyArray;
468
469import com.google.android.collect.Lists;
470import com.google.android.collect.Maps;
471
472import org.xmlpull.v1.XmlPullParser;
473import org.xmlpull.v1.XmlPullParserException;
474import org.xmlpull.v1.XmlSerializer;
475
476import java.io.File;
477import java.io.FileDescriptor;
478import java.io.FileInputStream;
479import java.io.FileNotFoundException;
480import java.io.FileOutputStream;
481import java.io.IOException;
482import java.io.InputStreamReader;
483import java.io.PrintWriter;
484import java.io.StringWriter;
485import java.io.UnsupportedEncodingException;
486import java.lang.ref.WeakReference;
487import java.nio.charset.StandardCharsets;
488import java.text.DateFormat;
489import java.text.SimpleDateFormat;
490import java.util.ArrayList;
491import java.util.Arrays;
492import java.util.Collections;
493import java.util.Comparator;
494import java.util.Date;
495import java.util.HashMap;
496import java.util.HashSet;
497import java.util.Iterator;
498import java.util.List;
499import java.util.Locale;
500import java.util.Map;
501import java.util.Objects;
502import java.util.Set;
503import java.util.concurrent.CountDownLatch;
504import java.util.concurrent.Executor;
505import java.util.concurrent.atomic.AtomicBoolean;
506import java.util.concurrent.atomic.AtomicLong;
507
508public class ActivityManagerService extends IActivityManager.Stub
509        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
510
511    /**
512     * Priority we boost main thread and RT of top app to.
513     */
514    public static final int TOP_APP_PRIORITY_BOOST = -10;
515
516    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
517    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
518    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
519    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
520    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
521    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
522    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
523    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
524    private static final String TAG_LRU = TAG + POSTFIX_LRU;
525    private static final String TAG_MU = TAG + POSTFIX_MU;
526    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
527    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
528    private static final String TAG_POWER = TAG + POSTFIX_POWER;
529    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
530    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
531    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
532    private static final String TAG_PSS = TAG + POSTFIX_PSS;
533    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
534    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
535    private static final String TAG_STACK = TAG + POSTFIX_STACK;
536    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
537    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
538    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
539    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
540
541    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
542    // here so that while the job scheduler can depend on AMS, the other way around
543    // need not be the case.
544    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
545
546    /** Control over CPU and battery monitoring */
547    // write battery stats every 30 minutes.
548    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
549    static final boolean MONITOR_CPU_USAGE = true;
550    // don't sample cpu less than every 5 seconds.
551    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
552    // wait possibly forever for next cpu sample.
553    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
554    static final boolean MONITOR_THREAD_CPU_USAGE = false;
555
556    // The flags that are set for all calls we make to the package manager.
557    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
558
559    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
560
561    // Maximum number of receivers an app can register.
562    private static final int MAX_RECEIVERS_ALLOWED_PER_APP = 1000;
563
564    // Amount of time after a call to stopAppSwitches() during which we will
565    // prevent further untrusted switches from happening.
566    static final long APP_SWITCH_DELAY_TIME = 5*1000;
567
568    // How long we wait for a launched process to attach to the activity manager
569    // before we decide it's never going to come up for real.
570    static final int PROC_START_TIMEOUT = 10*1000;
571    // How long we wait for an attached process to publish its content providers
572    // before we decide it must be hung.
573    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
574
575    // How long we wait for a launched process to attach to the activity manager
576    // before we decide it's never going to come up for real, when the process was
577    // started with a wrapper for instrumentation (such as Valgrind) because it
578    // could take much longer than usual.
579    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
580
581    // How long we allow a receiver to run before giving up on it.
582    static final int BROADCAST_FG_TIMEOUT = 10*1000;
583    static final int BROADCAST_BG_TIMEOUT = 60*1000;
584
585    // How long we wait until we timeout on key dispatching.
586    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
587
588    // How long we wait until we timeout on key dispatching during instrumentation.
589    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
590
591    // Disable hidden API checks for the newly started instrumentation.
592    // Must be kept in sync with Am.
593    private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
594
595    // How long to wait in getAssistContextExtras for the activity and foreground services
596    // to respond with the result.
597    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
598
599    // How long top wait when going through the modern assist (which doesn't need to block
600    // on getting this result before starting to launch its UI).
601    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
602
603    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
604    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
605
606    // Maximum number of persisted Uri grants a package is allowed
607    static final int MAX_PERSISTED_URI_GRANTS = 128;
608
609    static final int MY_PID = myPid();
610
611    static final String[] EMPTY_STRING_ARRAY = new String[0];
612
613    // How many bytes to write into the dropbox log before truncating
614    static final int DROPBOX_MAX_SIZE = 192 * 1024;
615    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
616    // as one line, but close enough for now.
617    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
618
619    /** If a UID observer takes more than this long, send a WTF. */
620    private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20;
621
622    // Access modes for handleIncomingUser.
623    static final int ALLOW_NON_FULL = 0;
624    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
625    static final int ALLOW_FULL_ONLY = 2;
626
627    // Necessary ApplicationInfo flags to mark an app as persistent
628    private static final int PERSISTENT_MASK =
629            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
630
631    // Intent sent when remote bugreport collection has been completed
632    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
633            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
634
635    // Used to indicate that an app transition should be animated.
636    static final boolean ANIMATE = true;
637
638    // Determines whether to take full screen screenshots
639    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
640
641    /**
642     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
643     */
644    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
645
646    /**
647     * State indicating that there is no need for any blocking for network.
648     */
649    @VisibleForTesting
650    static final int NETWORK_STATE_NO_CHANGE = 0;
651
652    /**
653     * State indicating that the main thread needs to be informed about the network wait.
654     */
655    @VisibleForTesting
656    static final int NETWORK_STATE_BLOCK = 1;
657
658    /**
659     * State indicating that any threads waiting for network state to get updated can be unblocked.
660     */
661    @VisibleForTesting
662    static final int NETWORK_STATE_UNBLOCK = 2;
663
664    // Max character limit for a notification title. If the notification title is larger than this
665    // the notification will not be legible to the user.
666    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
667
668    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
669
670    /** All system services */
671    SystemServiceManager mSystemServiceManager;
672
673    // Wrapper around VoiceInteractionServiceManager
674    private AssistUtils mAssistUtils;
675
676    // Keeps track of the active voice interaction service component, notified from
677    // VoiceInteractionManagerService
678    ComponentName mActiveVoiceInteractionServiceComponent;
679
680    private Installer mInstaller;
681
682    /** Run all ActivityStacks through this */
683    final ActivityStackSupervisor mStackSupervisor;
684    private final KeyguardController mKeyguardController;
685
686    private final ActivityStartController mActivityStartController;
687
688    private final ClientLifecycleManager mLifecycleManager;
689
690    final TaskChangeNotificationController mTaskChangeNotificationController;
691
692    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
693
694    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
695
696    public final IntentFirewall mIntentFirewall;
697
698    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
699    // default action automatically.  Important for devices without direct input
700    // devices.
701    private boolean mShowDialogs = true;
702
703    private final VrController mVrController;
704
705    // VR Vr2d Display Id.
706    int mVr2dDisplayId = INVALID_DISPLAY;
707
708    // Whether we should use SCHED_FIFO for UI and RenderThreads.
709    private boolean mUseFifoUiScheduling = false;
710
711    private static final String SYSUI_COMPONENT_NAME = "com.android.systemui/.SystemUIService";
712
713    BroadcastQueue mFgBroadcastQueue;
714    BroadcastQueue mBgBroadcastQueue;
715    // Convenient for easy iteration over the queues. Foreground is first
716    // so that dispatch of foreground broadcasts gets precedence.
717    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
718
719    BroadcastStats mLastBroadcastStats;
720    BroadcastStats mCurBroadcastStats;
721
722    BroadcastQueue broadcastQueueForIntent(Intent intent) {
723        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
724        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
725                "Broadcast intent " + intent + " on "
726                + (isFg ? "foreground" : "background") + " queue");
727        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
728    }
729
730    /**
731     * The last resumed activity. This is identical to the current resumed activity most
732     * of the time but could be different when we're pausing one activity before we resume
733     * another activity.
734     */
735    private ActivityRecord mLastResumedActivity;
736
737    /**
738     * If non-null, we are tracking the time the user spends in the currently focused app.
739     */
740    private AppTimeTracker mCurAppTimeTracker;
741
742    /**
743     * List of intents that were used to start the most recent tasks.
744     */
745    private final RecentTasks mRecentTasks;
746
747    /**
748     * For addAppTask: cached of the last activity component that was added.
749     */
750    ComponentName mLastAddedTaskComponent;
751
752    /**
753     * For addAppTask: cached of the last activity uid that was added.
754     */
755    int mLastAddedTaskUid;
756
757    /**
758     * For addAppTask: cached of the last ActivityInfo that was added.
759     */
760    ActivityInfo mLastAddedTaskActivity;
761
762    /**
763     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
764     */
765    String mDeviceOwnerName;
766
767    /**
768     * The controller for all operations related to locktask.
769     */
770    final LockTaskController mLockTaskController;
771
772    final UserController mUserController;
773
774    /**
775     * Packages that are being allowed to perform unrestricted app switches.  Mapping is
776     * User -> Type -> uid.
777     */
778    final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
779
780    final AppErrors mAppErrors;
781
782    final AppWarnings mAppWarnings;
783
784    /**
785     * Dump of the activity state at the time of the last ANR. Cleared after
786     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
787     */
788    String mLastANRState;
789
790    /**
791     * Indicates the maximum time spent waiting for the network rules to get updated.
792     */
793    @VisibleForTesting
794    long mWaitForNetworkTimeoutMs;
795
796    /** Total # of UID change events dispatched, shown in dumpsys. */
797    int mUidChangeDispatchCount;
798
799    /**
800     * Helper class which strips out priority and proto arguments then calls the dump function with
801     * the appropriate arguments. If priority arguments are omitted, function calls the legacy
802     * dump command.
803     * If priority arguments are omitted all sections are dumped, otherwise sections are dumped
804     * according to their priority.
805     */
806    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
807        @Override
808        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
809                boolean asProto) {
810            if (asProto) return;
811            doDump(fd, pw, new String[]{"activities"}, asProto);
812            doDump(fd, pw, new String[]{"service", SYSUI_COMPONENT_NAME}, asProto);
813        }
814
815        @Override
816        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
817            doDump(fd, pw, new String[]{"-a", "--normal-priority"}, asProto);
818        }
819
820        @Override
821        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
822            doDump(fd, pw, args, asProto);
823        }
824    };
825
826    public boolean canShowErrorDialogs() {
827        return mShowDialogs && !mSleeping && !mShuttingDown
828                && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
829                && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
830                        mUserController.getCurrentUserId())
831                && !(UserManager.isDeviceInDemoMode(mContext)
832                        && mUserController.getCurrentUser().isDemo());
833    }
834
835    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
836            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
837
838    static void boostPriorityForLockedSection() {
839        sThreadPriorityBooster.boost();
840    }
841
842    static void resetPriorityAfterLockedSection() {
843        sThreadPriorityBooster.reset();
844    }
845
846    public class PendingAssistExtras extends Binder implements Runnable {
847        public final ActivityRecord activity;
848        public boolean isHome;
849        public final Bundle extras;
850        public final Intent intent;
851        public final String hint;
852        public final IAssistDataReceiver receiver;
853        public final int userHandle;
854        public boolean haveResult = false;
855        public Bundle result = null;
856        public AssistStructure structure = null;
857        public AssistContent content = null;
858        public Bundle receiverExtras;
859
860        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
861                String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
862                int _userHandle) {
863            activity = _activity;
864            extras = _extras;
865            intent = _intent;
866            hint = _hint;
867            receiver = _receiver;
868            receiverExtras = _receiverExtras;
869            userHandle = _userHandle;
870        }
871
872        @Override
873        public void run() {
874            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
875            synchronized (this) {
876                haveResult = true;
877                notifyAll();
878            }
879            pendingAssistExtrasTimedOut(this);
880        }
881    }
882
883    final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
884
885    /**
886     * Process management.
887     */
888    final ProcessList mProcessList = new ProcessList();
889
890    /**
891     * All of the applications we currently have running organized by name.
892     * The keys are strings of the application package name (as
893     * returned by the package manager), and the keys are ApplicationRecord
894     * objects.
895     */
896    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
897
898    /**
899     * Tracking long-term execution of processes to look for abuse and other
900     * bad app behavior.
901     */
902    final ProcessStatsService mProcessStats;
903
904    /**
905     * The currently running isolated processes.
906     */
907    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
908
909    /**
910     * Counter for assigning isolated process uids, to avoid frequently reusing the
911     * same ones.
912     */
913    int mNextIsolatedProcessUid = 0;
914
915    /**
916     * The currently running heavy-weight process, if any.
917     */
918    ProcessRecord mHeavyWeightProcess = null;
919
920    /**
921     * Non-persistent appId whitelist for background restrictions
922     */
923    int[] mBackgroundAppIdWhitelist = new int[] {
924            BLUETOOTH_UID
925    };
926
927    /**
928     * Broadcast actions that will always be deliverable to unlaunched/background apps
929     */
930    ArraySet<String> mBackgroundLaunchBroadcasts;
931
932    /**
933     * All of the processes we currently have running organized by pid.
934     * The keys are the pid running the application.
935     *
936     * <p>NOTE: This object is protected by its own lock, NOT the global
937     * activity manager lock!
938     */
939    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
940
941    /**
942     * All of the processes that have been forced to be important.  The key
943     * is the pid of the caller who requested it (we hold a death
944     * link on it).
945     */
946    abstract class ImportanceToken implements IBinder.DeathRecipient {
947        final int pid;
948        final IBinder token;
949        final String reason;
950
951        ImportanceToken(int _pid, IBinder _token, String _reason) {
952            pid = _pid;
953            token = _token;
954            reason = _reason;
955        }
956
957        @Override
958        public String toString() {
959            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
960                    + " " + reason + " " + pid + " " + token + " }";
961        }
962
963        void writeToProto(ProtoOutputStream proto, long fieldId) {
964            final long pToken = proto.start(fieldId);
965            proto.write(ImportanceTokenProto.PID, pid);
966            if (token != null) {
967                proto.write(ImportanceTokenProto.TOKEN, token.toString());
968            }
969            proto.write(ImportanceTokenProto.REASON, reason);
970            proto.end(pToken);
971        }
972    }
973    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
974
975    /**
976     * List of records for processes that someone had tried to start before the
977     * system was ready.  We don't start them at that point, but ensure they
978     * are started by the time booting is complete.
979     */
980    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
981
982    /**
983     * List of persistent applications that are in the process
984     * of being started.
985     */
986    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
987
988    /**
989     * Processes that are being forcibly torn down.
990     */
991    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
992
993    /**
994     * List of running applications, sorted by recent usage.
995     * The first entry in the list is the least recently used.
996     */
997    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
998
999    /**
1000     * Where in mLruProcesses that the processes hosting activities start.
1001     */
1002    int mLruProcessActivityStart = 0;
1003
1004    /**
1005     * Where in mLruProcesses that the processes hosting services start.
1006     * This is after (lower index) than mLruProcessesActivityStart.
1007     */
1008    int mLruProcessServiceStart = 0;
1009
1010    /**
1011     * List of processes that should gc as soon as things are idle.
1012     */
1013    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
1014
1015    /**
1016     * Processes we want to collect PSS data from.
1017     */
1018    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
1019
1020    private boolean mBinderTransactionTrackingEnabled = false;
1021
1022    /**
1023     * Last time we requested PSS data of all processes.
1024     */
1025    long mLastFullPssTime = SystemClock.uptimeMillis();
1026
1027    /**
1028     * If set, the next time we collect PSS data we should do a full collection
1029     * with data from native processes and the kernel.
1030     */
1031    boolean mFullPssPending = false;
1032
1033    /**
1034     * This is the process holding what we currently consider to be
1035     * the "home" activity.
1036     */
1037    ProcessRecord mHomeProcess;
1038
1039    /**
1040     * This is the process holding the activity the user last visited that
1041     * is in a different process from the one they are currently in.
1042     */
1043    ProcessRecord mPreviousProcess;
1044
1045    /**
1046     * The time at which the previous process was last visible.
1047     */
1048    long mPreviousProcessVisibleTime;
1049
1050    /**
1051     * Track all uids that have actively running processes.
1052     */
1053    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
1054
1055    /**
1056     * This is for verifying the UID report flow.
1057     */
1058    static final boolean VALIDATE_UID_STATES = true;
1059    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
1060
1061    /**
1062     * Packages that the user has asked to have run in screen size
1063     * compatibility mode instead of filling the screen.
1064     */
1065    final CompatModePackages mCompatModePackages;
1066
1067    /**
1068     * Set of IntentSenderRecord objects that are currently active.
1069     */
1070    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1071            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1072
1073    /**
1074     * Fingerprints (hashCode()) of stack traces that we've
1075     * already logged DropBox entries for.  Guarded by itself.  If
1076     * something (rogue user app) forces this over
1077     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1078     */
1079    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1080    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1081
1082    /**
1083     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1084     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1085     */
1086    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1087
1088    /**
1089     * Resolver for broadcast intents to registered receivers.
1090     * Holds BroadcastFilter (subclass of IntentFilter).
1091     */
1092    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1093            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1094        @Override
1095        protected boolean allowFilterResult(
1096                BroadcastFilter filter, List<BroadcastFilter> dest) {
1097            IBinder target = filter.receiverList.receiver.asBinder();
1098            for (int i = dest.size() - 1; i >= 0; i--) {
1099                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1100                    return false;
1101                }
1102            }
1103            return true;
1104        }
1105
1106        @Override
1107        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1108            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1109                    || userId == filter.owningUserId) {
1110                return super.newResult(filter, match, userId);
1111            }
1112            return null;
1113        }
1114
1115        @Override
1116        protected BroadcastFilter[] newArray(int size) {
1117            return new BroadcastFilter[size];
1118        }
1119
1120        @Override
1121        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1122            return packageName.equals(filter.packageName);
1123        }
1124    };
1125
1126    /**
1127     * State of all active sticky broadcasts per user.  Keys are the action of the
1128     * sticky Intent, values are an ArrayList of all broadcasted intents with
1129     * that action (which should usually be one).  The SparseArray is keyed
1130     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1131     * for stickies that are sent to all users.
1132     */
1133    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1134            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1135
1136    final ActiveServices mServices;
1137
1138    final static class Association {
1139        final int mSourceUid;
1140        final String mSourceProcess;
1141        final int mTargetUid;
1142        final ComponentName mTargetComponent;
1143        final String mTargetProcess;
1144
1145        int mCount;
1146        long mTime;
1147
1148        int mNesting;
1149        long mStartTime;
1150
1151        // states of the source process when the bind occurred.
1152        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1153        long mLastStateUptime;
1154        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1155                - ActivityManager.MIN_PROCESS_STATE+1];
1156
1157        Association(int sourceUid, String sourceProcess, int targetUid,
1158                ComponentName targetComponent, String targetProcess) {
1159            mSourceUid = sourceUid;
1160            mSourceProcess = sourceProcess;
1161            mTargetUid = targetUid;
1162            mTargetComponent = targetComponent;
1163            mTargetProcess = targetProcess;
1164        }
1165    }
1166
1167    /**
1168     * When service association tracking is enabled, this is all of the associations we
1169     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1170     * -> association data.
1171     */
1172    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1173            mAssociations = new SparseArray<>();
1174    boolean mTrackingAssociations;
1175
1176    /**
1177     * Backup/restore process management
1178     */
1179    String mBackupAppName = null;
1180    BackupRecord mBackupTarget = null;
1181
1182    final ProviderMap mProviderMap;
1183
1184    /**
1185     * List of content providers who have clients waiting for them.  The
1186     * application is currently being launched and the provider will be
1187     * removed from this list once it is published.
1188     */
1189    final ArrayList<ContentProviderRecord> mLaunchingProviders
1190            = new ArrayList<ContentProviderRecord>();
1191
1192    /**
1193     * File storing persisted {@link #mGrantedUriPermissions}.
1194     */
1195    private final AtomicFile mGrantFile;
1196
1197    /** XML constants used in {@link #mGrantFile} */
1198    private static final String TAG_URI_GRANTS = "uri-grants";
1199    private static final String TAG_URI_GRANT = "uri-grant";
1200    private static final String ATTR_USER_HANDLE = "userHandle";
1201    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1202    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1203    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1204    private static final String ATTR_TARGET_PKG = "targetPkg";
1205    private static final String ATTR_URI = "uri";
1206    private static final String ATTR_MODE_FLAGS = "modeFlags";
1207    private static final String ATTR_CREATED_TIME = "createdTime";
1208    private static final String ATTR_PREFIX = "prefix";
1209
1210    /**
1211     * Global set of specific {@link Uri} permissions that have been granted.
1212     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1213     * to {@link UriPermission#uri} to {@link UriPermission}.
1214     */
1215    @GuardedBy("this")
1216    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1217            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1218
1219    public static class GrantUri {
1220        public final int sourceUserId;
1221        public final Uri uri;
1222        public boolean prefix;
1223
1224        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1225            this.sourceUserId = sourceUserId;
1226            this.uri = uri;
1227            this.prefix = prefix;
1228        }
1229
1230        @Override
1231        public int hashCode() {
1232            int hashCode = 1;
1233            hashCode = 31 * hashCode + sourceUserId;
1234            hashCode = 31 * hashCode + uri.hashCode();
1235            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1236            return hashCode;
1237        }
1238
1239        @Override
1240        public boolean equals(Object o) {
1241            if (o instanceof GrantUri) {
1242                GrantUri other = (GrantUri) o;
1243                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1244                        && prefix == other.prefix;
1245            }
1246            return false;
1247        }
1248
1249        @Override
1250        public String toString() {
1251            String result = uri.toString() + " [user " + sourceUserId + "]";
1252            if (prefix) result += " [prefix]";
1253            return result;
1254        }
1255
1256        public String toSafeString() {
1257            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1258            if (prefix) result += " [prefix]";
1259            return result;
1260        }
1261
1262        public void writeToProto(ProtoOutputStream proto, long fieldId) {
1263            long token = proto.start(fieldId);
1264            proto.write(GrantUriProto.URI, uri.toString());
1265            proto.write(GrantUriProto.SOURCE_USER_ID, sourceUserId);
1266            proto.end(token);
1267        }
1268
1269        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1270            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1271                    ContentProvider.getUriWithoutUserId(uri), false);
1272        }
1273    }
1274
1275    CoreSettingsObserver mCoreSettingsObserver;
1276
1277    FontScaleSettingObserver mFontScaleSettingObserver;
1278
1279    private final class FontScaleSettingObserver extends ContentObserver {
1280        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1281
1282        public FontScaleSettingObserver() {
1283            super(mHandler);
1284            ContentResolver resolver = mContext.getContentResolver();
1285            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1286        }
1287
1288        @Override
1289        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1290            if (mFontScaleUri.equals(uri)) {
1291                updateFontScaleIfNeeded(userId);
1292            }
1293        }
1294    }
1295
1296    DevelopmentSettingsObserver mDevelopmentSettingsObserver;
1297
1298    private final class DevelopmentSettingsObserver extends ContentObserver {
1299        private final Uri mUri = Settings.Global
1300                .getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
1301
1302        private final ComponentName mBugreportStorageProvider = new ComponentName(
1303                "com.android.shell", "com.android.shell.BugreportStorageProvider");
1304
1305        public DevelopmentSettingsObserver() {
1306            super(mHandler);
1307            mContext.getContentResolver().registerContentObserver(mUri, false, this,
1308                    UserHandle.USER_ALL);
1309            // Always kick once to ensure that we match current state
1310            onChange();
1311        }
1312
1313        @Override
1314        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1315            if (mUri.equals(uri)) {
1316                onChange();
1317            }
1318        }
1319
1320        public void onChange() {
1321            final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
1322                    Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, Build.IS_ENG ? 1 : 0) != 0;
1323            mContext.getPackageManager().setComponentEnabledSetting(mBugreportStorageProvider,
1324                    enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1325                            : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
1326                    0);
1327        }
1328    }
1329
1330    /**
1331     * Thread-local storage used to carry caller permissions over through
1332     * indirect content-provider access.
1333     */
1334    private class Identity {
1335        public final IBinder token;
1336        public final int pid;
1337        public final int uid;
1338
1339        Identity(IBinder _token, int _pid, int _uid) {
1340            token = _token;
1341            pid = _pid;
1342            uid = _uid;
1343        }
1344    }
1345
1346    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1347
1348    /**
1349     * All information we have collected about the runtime performance of
1350     * any user id that can impact battery performance.
1351     */
1352    final BatteryStatsService mBatteryStatsService;
1353
1354    /**
1355     * Information about component usage
1356     */
1357    UsageStatsManagerInternal mUsageStatsService;
1358
1359    /**
1360     * Access to DeviceIdleController service.
1361     */
1362    DeviceIdleController.LocalService mLocalDeviceIdleController;
1363
1364    /**
1365     * Set of app ids that are whitelisted for device idle and thus background check.
1366     */
1367    int[] mDeviceIdleWhitelist = new int[0];
1368
1369    /**
1370     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1371     */
1372    int[] mDeviceIdleTempWhitelist = new int[0];
1373
1374    static final class PendingTempWhitelist {
1375        final int targetUid;
1376        final long duration;
1377        final String tag;
1378
1379        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1380            targetUid = _targetUid;
1381            duration = _duration;
1382            tag = _tag;
1383        }
1384
1385        void writeToProto(ProtoOutputStream proto, long fieldId) {
1386            final long token = proto.start(fieldId);
1387            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
1388            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
1389            proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TAG, tag);
1390            proto.end(token);
1391        }
1392    }
1393
1394    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1395
1396    /**
1397     * Information about and control over application operations
1398     */
1399    final AppOpsService mAppOpsService;
1400
1401    /** Current sequencing integer of the configuration, for skipping old configurations. */
1402    private int mConfigurationSeq;
1403
1404    /**
1405     * Temp object used when global and/or display override configuration is updated. It is also
1406     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1407     * anyone...
1408     */
1409    private Configuration mTempConfig = new Configuration();
1410
1411    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1412            new UpdateConfigurationResult();
1413    private static final class UpdateConfigurationResult {
1414        // Configuration changes that were updated.
1415        int changes;
1416        // If the activity was relaunched to match the new configuration.
1417        boolean activityRelaunched;
1418
1419        void reset() {
1420            changes = 0;
1421            activityRelaunched = false;
1422        }
1423    }
1424
1425    boolean mSuppressResizeConfigChanges;
1426
1427    /**
1428     * Hardware-reported OpenGLES version.
1429     */
1430    final int GL_ES_VERSION;
1431
1432    /**
1433     * List of initialization arguments to pass to all processes when binding applications to them.
1434     * For example, references to the commonly used services.
1435     */
1436    HashMap<String, IBinder> mAppBindArgs;
1437    HashMap<String, IBinder> mIsolatedAppBindArgs;
1438
1439    /**
1440     * Temporary to avoid allocations.  Protected by main lock.
1441     */
1442    final StringBuilder mStringBuilder = new StringBuilder(256);
1443
1444    /**
1445     * Used to control how we initialize the service.
1446     */
1447    ComponentName mTopComponent;
1448    String mTopAction = Intent.ACTION_MAIN;
1449    String mTopData;
1450
1451    volatile boolean mProcessesReady = false;
1452    volatile boolean mSystemReady = false;
1453    volatile boolean mOnBattery = false;
1454    volatile int mFactoryTest;
1455
1456    @GuardedBy("this") boolean mBooting = false;
1457    @GuardedBy("this") boolean mCallFinishBooting = false;
1458    @GuardedBy("this") boolean mBootAnimationComplete = false;
1459    @GuardedBy("this") boolean mLaunchWarningShown = false;
1460    private @GuardedBy("this") boolean mCheckedForSetup = false;
1461
1462    final Context mContext;
1463
1464    /**
1465     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1466     * change at runtime. Use mContext for non-UI purposes.
1467     */
1468    final Context mUiContext;
1469
1470    /**
1471     * The time at which we will allow normal application switches again,
1472     * after a call to {@link #stopAppSwitches()}.
1473     */
1474    long mAppSwitchesAllowedTime;
1475
1476    /**
1477     * This is set to true after the first switch after mAppSwitchesAllowedTime
1478     * is set; any switches after that will clear the time.
1479     */
1480    boolean mDidAppSwitch;
1481
1482    /**
1483     * Last time (in uptime) at which we checked for power usage.
1484     */
1485    long mLastPowerCheckUptime;
1486
1487    /**
1488     * Set while we are wanting to sleep, to prevent any
1489     * activities from being started/resumed.
1490     *
1491     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1492     *
1493     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1494     * while in the sleep state until there is a pending transition out of sleep, in which case
1495     * mSleeping is set to false, and remains false while awake.
1496     *
1497     * Whether mSleeping can quickly toggled between true/false without the device actually
1498     * display changing states is undefined.
1499     */
1500    private boolean mSleeping = false;
1501
1502    /**
1503     * The process state used for processes that are running the top activities.
1504     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1505     */
1506    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1507
1508    /**
1509     * Set while we are running a voice interaction.  This overrides
1510     * sleeping while it is active.
1511     */
1512    IVoiceInteractionSession mRunningVoice;
1513
1514    /**
1515     * For some direct access we need to power manager.
1516     */
1517    PowerManagerInternal mLocalPowerManager;
1518
1519    /**
1520     * We want to hold a wake lock while running a voice interaction session, since
1521     * this may happen with the screen off and we need to keep the CPU running to
1522     * be able to continue to interact with the user.
1523     */
1524    PowerManager.WakeLock mVoiceWakeLock;
1525
1526    /**
1527     * State of external calls telling us if the device is awake or asleep.
1528     */
1529    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1530
1531    /**
1532     * Set if we are shutting down the system, similar to sleeping.
1533     */
1534    boolean mShuttingDown = false;
1535
1536    /**
1537     * Current sequence id for oom_adj computation traversal.
1538     */
1539    int mAdjSeq = 0;
1540
1541    /**
1542     * Current sequence id for process LRU updating.
1543     */
1544    int mLruSeq = 0;
1545
1546    /**
1547     * Keep track of the non-cached/empty process we last found, to help
1548     * determine how to distribute cached/empty processes next time.
1549     */
1550    int mNumNonCachedProcs = 0;
1551
1552    /**
1553     * Keep track of the number of cached hidden procs, to balance oom adj
1554     * distribution between those and empty procs.
1555     */
1556    int mNumCachedHiddenProcs = 0;
1557
1558    /**
1559     * Keep track of the number of service processes we last found, to
1560     * determine on the next iteration which should be B services.
1561     */
1562    int mNumServiceProcs = 0;
1563    int mNewNumAServiceProcs = 0;
1564    int mNewNumServiceProcs = 0;
1565
1566    /**
1567     * Allow the current computed overall memory level of the system to go down?
1568     * This is set to false when we are killing processes for reasons other than
1569     * memory management, so that the now smaller process list will not be taken as
1570     * an indication that memory is tighter.
1571     */
1572    boolean mAllowLowerMemLevel = false;
1573
1574    /**
1575     * The last computed memory level, for holding when we are in a state that
1576     * processes are going away for other reasons.
1577     */
1578    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1579
1580    /**
1581     * The last total number of process we have, to determine if changes actually look
1582     * like a shrinking number of process due to lower RAM.
1583     */
1584    int mLastNumProcesses;
1585
1586    /**
1587     * The uptime of the last time we performed idle maintenance.
1588     */
1589    long mLastIdleTime = SystemClock.uptimeMillis();
1590
1591    /**
1592     * Total time spent with RAM that has been added in the past since the last idle time.
1593     */
1594    long mLowRamTimeSinceLastIdle = 0;
1595
1596    /**
1597     * If RAM is currently low, when that horrible situation started.
1598     */
1599    long mLowRamStartTime = 0;
1600
1601    /**
1602     * For reporting to battery stats the current top application.
1603     */
1604    private String mCurResumedPackage = null;
1605    private int mCurResumedUid = -1;
1606
1607    /**
1608     * For reporting to battery stats the apps currently running foreground
1609     * service.  The ProcessMap is package/uid tuples; each of these contain
1610     * an array of the currently foreground processes.
1611     */
1612    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1613            = new ProcessMap<ArrayList<ProcessRecord>>();
1614
1615    /**
1616     * Set if the systemServer made a call to enterSafeMode.
1617     */
1618    boolean mSafeMode;
1619
1620    /**
1621     * If true, we are running under a test environment so will sample PSS from processes
1622     * much more rapidly to try to collect better data when the tests are rapidly
1623     * running through apps.
1624     */
1625    boolean mTestPssMode = false;
1626
1627    String mDebugApp = null;
1628    boolean mWaitForDebugger = false;
1629    boolean mDebugTransient = false;
1630    String mOrigDebugApp = null;
1631    boolean mOrigWaitForDebugger = false;
1632    boolean mAlwaysFinishActivities = false;
1633    boolean mForceResizableActivities;
1634    /**
1635     * Flag that indicates if multi-window is enabled.
1636     *
1637     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1638     * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1639     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1640     * At least one of the forms of multi-window must be enabled in order for this flag to be
1641     * initialized to 'true'.
1642     *
1643     * @see #mSupportsSplitScreenMultiWindow
1644     * @see #mSupportsFreeformWindowManagement
1645     * @see #mSupportsPictureInPicture
1646     * @see #mSupportsMultiDisplay
1647     */
1648    boolean mSupportsMultiWindow;
1649    boolean mSupportsSplitScreenMultiWindow;
1650    boolean mSupportsFreeformWindowManagement;
1651    boolean mSupportsPictureInPicture;
1652    boolean mSupportsMultiDisplay;
1653    boolean mSupportsLeanbackOnly;
1654    IActivityController mController = null;
1655    boolean mControllerIsAMonkey = false;
1656    String mProfileApp = null;
1657    ProcessRecord mProfileProc = null;
1658    ProfilerInfo mProfilerInfo = null;
1659
1660    /**
1661     * Stores a map of process name -> agent string. When a process is started and mAgentAppMap
1662     * is not null, this map is checked and the mapped agent installed during bind-time. Note:
1663     * A non-null agent in mProfileInfo overrides this.
1664     */
1665    private @Nullable Map<String, String> mAppAgentMap = null;
1666
1667    int mProfileType = 0;
1668    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1669    String mMemWatchDumpProcName;
1670    String mMemWatchDumpFile;
1671    int mMemWatchDumpPid;
1672    int mMemWatchDumpUid;
1673    String mTrackAllocationApp = null;
1674    String mNativeDebuggingApp = null;
1675
1676    final long[] mTmpLong = new long[3];
1677
1678    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1679
1680    /**
1681     * A global counter for generating sequence numbers.
1682     * This value will be used when incrementing sequence numbers in individual uidRecords.
1683     *
1684     * Having a global counter ensures that seq numbers are monotonically increasing for a
1685     * particular uid even when the uidRecord is re-created.
1686     */
1687    @GuardedBy("this")
1688    @VisibleForTesting
1689    long mProcStateSeqCounter = 0;
1690
1691    /**
1692     * A global counter for generating sequence numbers to uniquely identify pending process starts.
1693     */
1694    @GuardedBy("this")
1695    private long mProcStartSeqCounter = 0;
1696
1697    /**
1698     * Contains {@link ProcessRecord} objects for pending process starts.
1699     *
1700     * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
1701     */
1702    @GuardedBy("this")
1703    private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
1704
1705    private final Injector mInjector;
1706
1707    static final class ProcessChangeItem {
1708        static final int CHANGE_ACTIVITIES = 1<<0;
1709        int changes;
1710        int uid;
1711        int pid;
1712        int processState;
1713        boolean foregroundActivities;
1714    }
1715
1716    static final class UidObserverRegistration {
1717        final int uid;
1718        final String pkg;
1719        final int which;
1720        final int cutpoint;
1721
1722        /**
1723         * Total # of callback calls that took more than {@link #SLOW_UID_OBSERVER_THRESHOLD_MS}.
1724         * We show it in dumpsys.
1725         */
1726        int mSlowDispatchCount;
1727
1728        /** Max time it took for each dispatch. */
1729        int mMaxDispatchTime;
1730
1731        final SparseIntArray lastProcStates;
1732
1733        // Please keep the enum lists in sync
1734        private static int[] ORIG_ENUMS = new int[]{
1735                ActivityManager.UID_OBSERVER_IDLE,
1736                ActivityManager.UID_OBSERVER_ACTIVE,
1737                ActivityManager.UID_OBSERVER_GONE,
1738                ActivityManager.UID_OBSERVER_PROCSTATE,
1739        };
1740        private static int[] PROTO_ENUMS = new int[]{
1741                ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
1742                ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
1743                ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
1744                ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
1745        };
1746
1747        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1748            uid = _uid;
1749            pkg = _pkg;
1750            which = _which;
1751            cutpoint = _cutpoint;
1752            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1753                lastProcStates = new SparseIntArray();
1754            } else {
1755                lastProcStates = null;
1756            }
1757        }
1758
1759        void writeToProto(ProtoOutputStream proto, long fieldId) {
1760            final long token = proto.start(fieldId);
1761            proto.write(UidObserverRegistrationProto.UID, uid);
1762            proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
1763            ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
1764                    which, ORIG_ENUMS, PROTO_ENUMS);
1765            proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
1766            if (lastProcStates != null) {
1767                final int NI = lastProcStates.size();
1768                for (int i=0; i<NI; i++) {
1769                    final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
1770                    proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i));
1771                    proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i));
1772                    proto.end(pToken);
1773                }
1774            }
1775            proto.end(token);
1776        }
1777    }
1778
1779    final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1780
1781    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1782    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1783
1784    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1785    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1786
1787    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1788    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1789
1790    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1791    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1792
1793    OomAdjObserver mCurOomAdjObserver;
1794    int mCurOomAdjUid;
1795
1796    interface OomAdjObserver {
1797        void onOomAdjMessage(String msg);
1798    }
1799
1800    /**
1801     * Runtime CPU use collection thread.  This object's lock is used to
1802     * perform synchronization with the thread (notifying it to run).
1803     */
1804    final Thread mProcessCpuThread;
1805
1806    /**
1807     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1808     * Must acquire this object's lock when accessing it.
1809     * NOTE: this lock will be held while doing long operations (trawling
1810     * through all processes in /proc), so it should never be acquired by
1811     * any critical paths such as when holding the main activity manager lock.
1812     */
1813    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1814            MONITOR_THREAD_CPU_USAGE);
1815    final AtomicLong mLastCpuTime = new AtomicLong(0);
1816    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1817    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1818
1819    long mLastWriteTime = 0;
1820
1821    /**
1822     * Used to retain an update lock when the foreground activity is in
1823     * immersive mode.
1824     */
1825    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1826
1827    /**
1828     * Set to true after the system has finished booting.
1829     */
1830    boolean mBooted = false;
1831
1832    WindowManagerService mWindowManager;
1833    final ActivityThread mSystemThread;
1834
1835    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1836        final ProcessRecord mApp;
1837        final int mPid;
1838        final IApplicationThread mAppThread;
1839
1840        AppDeathRecipient(ProcessRecord app, int pid,
1841                IApplicationThread thread) {
1842            if (DEBUG_ALL) Slog.v(
1843                TAG, "New death recipient " + this
1844                + " for thread " + thread.asBinder());
1845            mApp = app;
1846            mPid = pid;
1847            mAppThread = thread;
1848        }
1849
1850        @Override
1851        public void binderDied() {
1852            if (DEBUG_ALL) Slog.v(
1853                TAG, "Death received in " + this
1854                + " for thread " + mAppThread.asBinder());
1855            synchronized(ActivityManagerService.this) {
1856                appDiedLocked(mApp, mPid, mAppThread, true);
1857            }
1858        }
1859    }
1860
1861    static final int SHOW_ERROR_UI_MSG = 1;
1862    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1863    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1864    static final int UPDATE_CONFIGURATION_MSG = 4;
1865    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1866    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1867    static final int SERVICE_TIMEOUT_MSG = 12;
1868    static final int UPDATE_TIME_ZONE = 13;
1869    static final int SHOW_UID_ERROR_UI_MSG = 14;
1870    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1871    static final int PROC_START_TIMEOUT_MSG = 20;
1872    static final int KILL_APPLICATION_MSG = 22;
1873    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1874    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1875    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1876    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1877    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1878    static final int CLEAR_DNS_CACHE_MSG = 28;
1879    static final int UPDATE_HTTP_PROXY_MSG = 29;
1880    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1881    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1882    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1883    static final int REPORT_MEM_USAGE_MSG = 33;
1884    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1885    static final int PERSIST_URI_GRANTS_MSG = 38;
1886    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1887    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1888    static final int FINISH_BOOTING_MSG = 45;
1889    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1890    static final int DISMISS_DIALOG_UI_MSG = 48;
1891    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1892    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1893    static final int DELETE_DUMPHEAP_MSG = 51;
1894    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1895    static final int REPORT_TIME_TRACKER_MSG = 54;
1896    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1897    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1898    static final int IDLE_UIDS_MSG = 58;
1899    static final int LOG_STACK_STATE = 60;
1900    static final int VR_MODE_CHANGE_MSG = 61;
1901    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1902    static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
1903    static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
1904    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1905    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1906    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1907    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1908    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1909
1910    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1911    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1912    static final int FIRST_COMPAT_MODE_MSG = 300;
1913    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1914
1915    static ServiceThread sKillThread = null;
1916    static KillHandler sKillHandler = null;
1917
1918    CompatModeDialog mCompatModeDialog;
1919    long mLastMemUsageReportTime = 0;
1920
1921    /**
1922     * Flag whether the current user is a "monkey", i.e. whether
1923     * the UI is driven by a UI automation tool.
1924     */
1925    private boolean mUserIsMonkey;
1926
1927    /** The dimensions of the thumbnails in the Recents UI. */
1928    int mThumbnailWidth;
1929    int mThumbnailHeight;
1930    float mFullscreenThumbnailScale;
1931
1932    final ServiceThread mHandlerThread;
1933    final MainHandler mHandler;
1934    final Handler mUiHandler;
1935    final ServiceThread mProcStartHandlerThread;
1936    final Handler mProcStartHandler;
1937
1938    final ActivityManagerConstants mConstants;
1939
1940    // Encapsulates the global setting "hidden_api_blacklist_exemptions"
1941    final HiddenApiBlacklist mHiddenApiBlacklist;
1942
1943    PackageManagerInternal mPackageManagerInt;
1944
1945    // VoiceInteraction session ID that changes for each new request except when
1946    // being called for multiwindow assist in a single session.
1947    private int mViSessionId = 1000;
1948
1949    final boolean mPermissionReviewRequired;
1950
1951    /**
1952     * Whether to force background check on all apps (for battery saver) or not.
1953     */
1954    boolean mForceBackgroundCheck;
1955
1956    private static String sTheRealBuildSerial = Build.UNKNOWN;
1957
1958    /**
1959     * Current global configuration information. Contains general settings for the entire system,
1960     * also corresponds to the merged configuration of the default display.
1961     */
1962    Configuration getGlobalConfiguration() {
1963        return mStackSupervisor.getConfiguration();
1964    }
1965
1966    final class KillHandler extends Handler {
1967        static final int KILL_PROCESS_GROUP_MSG = 4000;
1968
1969        public KillHandler(Looper looper) {
1970            super(looper, null, true);
1971        }
1972
1973        @Override
1974        public void handleMessage(Message msg) {
1975            switch (msg.what) {
1976                case KILL_PROCESS_GROUP_MSG:
1977                {
1978                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1979                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1980                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1981                }
1982                break;
1983
1984                default:
1985                    super.handleMessage(msg);
1986            }
1987        }
1988    }
1989
1990    final class UiHandler extends Handler {
1991        public UiHandler() {
1992            super(com.android.server.UiThread.get().getLooper(), null, true);
1993        }
1994
1995        @Override
1996        public void handleMessage(Message msg) {
1997            switch (msg.what) {
1998            case SHOW_ERROR_UI_MSG: {
1999                mAppErrors.handleShowAppErrorUi(msg);
2000                ensureBootCompleted();
2001            } break;
2002            case SHOW_NOT_RESPONDING_UI_MSG: {
2003                mAppErrors.handleShowAnrUi(msg);
2004                ensureBootCompleted();
2005            } break;
2006            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
2007                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
2008                synchronized (ActivityManagerService.this) {
2009                    ProcessRecord proc = (ProcessRecord) data.get("app");
2010                    if (proc == null) {
2011                        Slog.e(TAG, "App not found when showing strict mode dialog.");
2012                        break;
2013                    }
2014                    if (proc.crashDialog != null) {
2015                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
2016                        return;
2017                    }
2018                    AppErrorResult res = (AppErrorResult) data.get("result");
2019                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
2020                        Dialog d = new StrictModeViolationDialog(mUiContext,
2021                                ActivityManagerService.this, res, proc);
2022                        d.show();
2023                        proc.crashDialog = d;
2024                    } else {
2025                        // The device is asleep, so just pretend that the user
2026                        // saw a crash dialog and hit "force quit".
2027                        res.set(0);
2028                    }
2029                }
2030                ensureBootCompleted();
2031            } break;
2032            case SHOW_FACTORY_ERROR_UI_MSG: {
2033                Dialog d = new FactoryErrorDialog(
2034                        mUiContext, msg.getData().getCharSequence("msg"));
2035                d.show();
2036                ensureBootCompleted();
2037            } break;
2038            case WAIT_FOR_DEBUGGER_UI_MSG: {
2039                synchronized (ActivityManagerService.this) {
2040                    ProcessRecord app = (ProcessRecord)msg.obj;
2041                    if (msg.arg1 != 0) {
2042                        if (!app.waitedForDebugger) {
2043                            Dialog d = new AppWaitingForDebuggerDialog(
2044                                    ActivityManagerService.this,
2045                                    mUiContext, app);
2046                            app.waitDialog = d;
2047                            app.waitedForDebugger = true;
2048                            d.show();
2049                        }
2050                    } else {
2051                        if (app.waitDialog != null) {
2052                            app.waitDialog.dismiss();
2053                            app.waitDialog = null;
2054                        }
2055                    }
2056                }
2057            } break;
2058            case SHOW_UID_ERROR_UI_MSG: {
2059                if (mShowDialogs) {
2060                    AlertDialog d = new BaseErrorDialog(mUiContext);
2061                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2062                    d.setCancelable(false);
2063                    d.setTitle(mUiContext.getText(R.string.android_system_label));
2064                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
2065                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2066                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2067                    d.show();
2068                }
2069            } break;
2070            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
2071                if (mShowDialogs) {
2072                    AlertDialog d = new BaseErrorDialog(mUiContext);
2073                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2074                    d.setCancelable(false);
2075                    d.setTitle(mUiContext.getText(R.string.android_system_label));
2076                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
2077                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2078                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2079                    d.show();
2080                }
2081            } break;
2082            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
2083                synchronized (ActivityManagerService.this) {
2084                    ActivityRecord ar = (ActivityRecord) msg.obj;
2085                    if (mCompatModeDialog != null) {
2086                        if (mCompatModeDialog.mAppInfo.packageName.equals(
2087                                ar.info.applicationInfo.packageName)) {
2088                            return;
2089                        }
2090                        mCompatModeDialog.dismiss();
2091                        mCompatModeDialog = null;
2092                    }
2093                    if (ar != null && false) {
2094                        if (mCompatModePackages.getPackageAskCompatModeLocked(
2095                                ar.packageName)) {
2096                            int mode = mCompatModePackages.computeCompatModeLocked(
2097                                    ar.info.applicationInfo);
2098                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
2099                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
2100                                mCompatModeDialog = new CompatModeDialog(
2101                                        ActivityManagerService.this, mUiContext,
2102                                        ar.info.applicationInfo);
2103                                mCompatModeDialog.show();
2104                            }
2105                        }
2106                    }
2107                }
2108                break;
2109            }
2110            case DISMISS_DIALOG_UI_MSG: {
2111                final Dialog d = (Dialog) msg.obj;
2112                d.dismiss();
2113                break;
2114            }
2115            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
2116                dispatchProcessesChanged();
2117                break;
2118            }
2119            case DISPATCH_PROCESS_DIED_UI_MSG: {
2120                final int pid = msg.arg1;
2121                final int uid = msg.arg2;
2122                dispatchProcessDied(pid, uid);
2123                break;
2124            }
2125            case DISPATCH_UIDS_CHANGED_UI_MSG: {
2126                dispatchUidsChanged();
2127            } break;
2128            case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
2129                dispatchOomAdjObserver((String)msg.obj);
2130            } break;
2131            case PUSH_TEMP_WHITELIST_UI_MSG: {
2132                pushTempWhitelist();
2133            } break;
2134            }
2135        }
2136    }
2137
2138    final class MainHandler extends Handler {
2139        public MainHandler(Looper looper) {
2140            super(looper, null, true);
2141        }
2142
2143        @Override
2144        public void handleMessage(Message msg) {
2145            switch (msg.what) {
2146            case UPDATE_CONFIGURATION_MSG: {
2147                final ContentResolver resolver = mContext.getContentResolver();
2148                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
2149                        msg.arg1);
2150            } break;
2151            case GC_BACKGROUND_PROCESSES_MSG: {
2152                synchronized (ActivityManagerService.this) {
2153                    performAppGcsIfAppropriateLocked();
2154                }
2155            } break;
2156            case SERVICE_TIMEOUT_MSG: {
2157                mServices.serviceTimeout((ProcessRecord)msg.obj);
2158            } break;
2159            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
2160                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
2161            } break;
2162            case SERVICE_FOREGROUND_CRASH_MSG: {
2163                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
2164            } break;
2165            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
2166                RemoteCallbackList<IResultReceiver> callbacks
2167                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
2168                int N = callbacks.beginBroadcast();
2169                for (int i = 0; i < N; i++) {
2170                    try {
2171                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
2172                    } catch (RemoteException e) {
2173                    }
2174                }
2175                callbacks.finishBroadcast();
2176            } break;
2177            case UPDATE_TIME_ZONE: {
2178                synchronized (ActivityManagerService.this) {
2179                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2180                        ProcessRecord r = mLruProcesses.get(i);
2181                        if (r.thread != null) {
2182                            try {
2183                                r.thread.updateTimeZone();
2184                            } catch (RemoteException ex) {
2185                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2186                            }
2187                        }
2188                    }
2189                }
2190            } break;
2191            case CLEAR_DNS_CACHE_MSG: {
2192                synchronized (ActivityManagerService.this) {
2193                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2194                        ProcessRecord r = mLruProcesses.get(i);
2195                        if (r.thread != null) {
2196                            try {
2197                                r.thread.clearDnsCache();
2198                            } catch (RemoteException ex) {
2199                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2200                            }
2201                        }
2202                    }
2203                }
2204            } break;
2205            case UPDATE_HTTP_PROXY_MSG: {
2206                ProxyInfo proxy = (ProxyInfo)msg.obj;
2207                String host = "";
2208                String port = "";
2209                String exclList = "";
2210                Uri pacFileUrl = Uri.EMPTY;
2211                if (proxy != null) {
2212                    host = proxy.getHost();
2213                    port = Integer.toString(proxy.getPort());
2214                    exclList = proxy.getExclusionListAsString();
2215                    pacFileUrl = proxy.getPacFileUrl();
2216                }
2217                synchronized (ActivityManagerService.this) {
2218                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2219                        ProcessRecord r = mLruProcesses.get(i);
2220                        // Don't dispatch to isolated processes as they can't access
2221                        // ConnectivityManager and don't have network privileges anyway.
2222                        if (r.thread != null && !r.isolated) {
2223                            try {
2224                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2225                            } catch (RemoteException ex) {
2226                                Slog.w(TAG, "Failed to update http proxy for: " +
2227                                        r.info.processName);
2228                            }
2229                        }
2230                    }
2231                }
2232            } break;
2233            case PROC_START_TIMEOUT_MSG: {
2234                ProcessRecord app = (ProcessRecord)msg.obj;
2235                synchronized (ActivityManagerService.this) {
2236                    processStartTimedOutLocked(app);
2237                }
2238            } break;
2239            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2240                ProcessRecord app = (ProcessRecord)msg.obj;
2241                synchronized (ActivityManagerService.this) {
2242                    processContentProviderPublishTimedOutLocked(app);
2243                }
2244            } break;
2245            case KILL_APPLICATION_MSG: {
2246                synchronized (ActivityManagerService.this) {
2247                    final int appId = msg.arg1;
2248                    final int userId = msg.arg2;
2249                    Bundle bundle = (Bundle)msg.obj;
2250                    String pkg = bundle.getString("pkg");
2251                    String reason = bundle.getString("reason");
2252                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2253                            false, userId, reason);
2254                }
2255            } break;
2256            case FINALIZE_PENDING_INTENT_MSG: {
2257                ((PendingIntentRecord)msg.obj).completeFinalize();
2258            } break;
2259            case POST_HEAVY_NOTIFICATION_MSG: {
2260                INotificationManager inm = NotificationManager.getService();
2261                if (inm == null) {
2262                    return;
2263                }
2264
2265                ActivityRecord root = (ActivityRecord)msg.obj;
2266                ProcessRecord process = root.app;
2267                if (process == null) {
2268                    return;
2269                }
2270
2271                try {
2272                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2273                    String text = mContext.getString(R.string.heavy_weight_notification,
2274                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2275                    Notification notification =
2276                            new Notification.Builder(context,
2277                                    SystemNotificationChannels.HEAVY_WEIGHT_APP)
2278                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2279                            .setWhen(0)
2280                            .setOngoing(true)
2281                            .setTicker(text)
2282                            .setColor(mContext.getColor(
2283                                    com.android.internal.R.color.system_notification_accent_color))
2284                            .setContentTitle(text)
2285                            .setContentText(
2286                                    mContext.getText(R.string.heavy_weight_notification_detail))
2287                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2288                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2289                                    new UserHandle(root.userId)))
2290                            .build();
2291                    try {
2292                        inm.enqueueNotificationWithTag("android", "android", null,
2293                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2294                                notification, root.userId);
2295                    } catch (RuntimeException e) {
2296                        Slog.w(ActivityManagerService.TAG,
2297                                "Error showing notification for heavy-weight app", e);
2298                    } catch (RemoteException e) {
2299                    }
2300                } catch (NameNotFoundException e) {
2301                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2302                }
2303            } break;
2304            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2305                INotificationManager inm = NotificationManager.getService();
2306                if (inm == null) {
2307                    return;
2308                }
2309                try {
2310                    inm.cancelNotificationWithTag("android", null,
2311                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2312                } catch (RuntimeException e) {
2313                    Slog.w(ActivityManagerService.TAG,
2314                            "Error canceling notification for service", e);
2315                } catch (RemoteException e) {
2316                }
2317            } break;
2318            case CHECK_EXCESSIVE_POWER_USE_MSG: {
2319                synchronized (ActivityManagerService.this) {
2320                    checkExcessivePowerUsageLocked();
2321                    removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2322                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2323                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2324                }
2325            } break;
2326            case REPORT_MEM_USAGE_MSG: {
2327                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2328                Thread thread = new Thread() {
2329                    @Override public void run() {
2330                        reportMemUsage(memInfos);
2331                    }
2332                };
2333                thread.start();
2334                break;
2335            }
2336            case IMMERSIVE_MODE_LOCK_MSG: {
2337                final boolean nextState = (msg.arg1 != 0);
2338                if (mUpdateLock.isHeld() != nextState) {
2339                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2340                            "Applying new update lock state '" + nextState
2341                            + "' for " + (ActivityRecord)msg.obj);
2342                    if (nextState) {
2343                        mUpdateLock.acquire();
2344                    } else {
2345                        mUpdateLock.release();
2346                    }
2347                }
2348                break;
2349            }
2350            case PERSIST_URI_GRANTS_MSG: {
2351                writeGrantedUriPermissions();
2352                break;
2353            }
2354            case UPDATE_TIME_PREFERENCE_MSG: {
2355                // The user's time format preference might have changed.
2356                // For convenience we re-use the Intent extra values.
2357                synchronized (ActivityManagerService.this) {
2358                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2359                        ProcessRecord r = mLruProcesses.get(i);
2360                        if (r.thread != null) {
2361                            try {
2362                                r.thread.updateTimePrefs(msg.arg1);
2363                            } catch (RemoteException ex) {
2364                                Slog.w(TAG, "Failed to update preferences for: "
2365                                        + r.info.processName);
2366                            }
2367                        }
2368                    }
2369                }
2370                break;
2371            }
2372            case ENTER_ANIMATION_COMPLETE_MSG: {
2373                synchronized (ActivityManagerService.this) {
2374                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2375                    if (r != null && r.app != null && r.app.thread != null) {
2376                        try {
2377                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2378                        } catch (RemoteException e) {
2379                        }
2380                    }
2381                }
2382                break;
2383            }
2384            case FINISH_BOOTING_MSG: {
2385                if (msg.arg1 != 0) {
2386                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2387                    finishBooting();
2388                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2389                }
2390                if (msg.arg2 != 0) {
2391                    enableScreenAfterBoot();
2392                }
2393                break;
2394            }
2395            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2396                try {
2397                    Locale l = (Locale) msg.obj;
2398                    IBinder service = ServiceManager.getService("mount");
2399                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2400                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2401                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2402                } catch (RemoteException e) {
2403                    Log.e(TAG, "Error storing locale for decryption UI", e);
2404                }
2405                break;
2406            }
2407            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2408                final int uid = msg.arg1;
2409                final byte[] firstPacket = (byte[]) msg.obj;
2410
2411                synchronized (mPidsSelfLocked) {
2412                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2413                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2414                        if (p.uid == uid) {
2415                            try {
2416                                p.thread.notifyCleartextNetwork(firstPacket);
2417                            } catch (RemoteException ignored) {
2418                            }
2419                        }
2420                    }
2421                }
2422                break;
2423            }
2424            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2425                final String procName;
2426                final int uid;
2427                final long memLimit;
2428                final String reportPackage;
2429                synchronized (ActivityManagerService.this) {
2430                    procName = mMemWatchDumpProcName;
2431                    uid = mMemWatchDumpUid;
2432                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2433                    if (val == null) {
2434                        val = mMemWatchProcesses.get(procName, 0);
2435                    }
2436                    if (val != null) {
2437                        memLimit = val.first;
2438                        reportPackage = val.second;
2439                    } else {
2440                        memLimit = 0;
2441                        reportPackage = null;
2442                    }
2443                }
2444                if (procName == null) {
2445                    return;
2446                }
2447
2448                if (DEBUG_PSS) Slog.d(TAG_PSS,
2449                        "Showing dump heap notification from " + procName + "/" + uid);
2450
2451                INotificationManager inm = NotificationManager.getService();
2452                if (inm == null) {
2453                    return;
2454                }
2455
2456                String text = mContext.getString(R.string.dump_heap_notification, procName);
2457
2458
2459                Intent deleteIntent = new Intent();
2460                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2461                Intent intent = new Intent();
2462                intent.setClassName("android", DumpHeapActivity.class.getName());
2463                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2464                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2465                if (reportPackage != null) {
2466                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2467                }
2468                int userId = UserHandle.getUserId(uid);
2469                Notification notification =
2470                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2471                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2472                        .setWhen(0)
2473                        .setOngoing(true)
2474                        .setAutoCancel(true)
2475                        .setTicker(text)
2476                        .setColor(mContext.getColor(
2477                                com.android.internal.R.color.system_notification_accent_color))
2478                        .setContentTitle(text)
2479                        .setContentText(
2480                                mContext.getText(R.string.dump_heap_notification_detail))
2481                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2482                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2483                                new UserHandle(userId)))
2484                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2485                                deleteIntent, 0, UserHandle.SYSTEM))
2486                        .build();
2487
2488                try {
2489                    inm.enqueueNotificationWithTag("android", "android", null,
2490                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2491                            notification, userId);
2492                } catch (RuntimeException e) {
2493                    Slog.w(ActivityManagerService.TAG,
2494                            "Error showing notification for dump heap", e);
2495                } catch (RemoteException e) {
2496                }
2497            } break;
2498            case DELETE_DUMPHEAP_MSG: {
2499                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2500                        null, DumpHeapActivity.JAVA_URI,
2501                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2502                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2503                        UserHandle.myUserId());
2504                synchronized (ActivityManagerService.this) {
2505                    mMemWatchDumpFile = null;
2506                    mMemWatchDumpProcName = null;
2507                    mMemWatchDumpPid = -1;
2508                    mMemWatchDumpUid = -1;
2509                }
2510            } break;
2511            case REPORT_TIME_TRACKER_MSG: {
2512                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2513                tracker.deliverResult(mContext);
2514            } break;
2515            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2516                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2517                try {
2518                    connection.shutdown();
2519                } catch (RemoteException e) {
2520                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2521                }
2522                // Only a UiAutomation can set this flag and now that
2523                // it is finished we make sure it is reset to its default.
2524                mUserIsMonkey = false;
2525            } break;
2526            case IDLE_UIDS_MSG: {
2527                idleUids();
2528            } break;
2529            case VR_MODE_CHANGE_MSG: {
2530                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2531                    return;
2532                }
2533                synchronized (ActivityManagerService.this) {
2534                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2535                    mWindowManager.disableNonVrUi(disableNonVrUi);
2536                    if (disableNonVrUi) {
2537                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2538                        // then remove the pinned stack.
2539                        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2540                    }
2541                }
2542            } break;
2543            case DISPATCH_SCREEN_AWAKE_MSG: {
2544                final boolean isAwake = msg.arg1 != 0;
2545                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2546                    mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2547                }
2548            } break;
2549            case DISPATCH_SCREEN_KEYGUARD_MSG: {
2550                final boolean isShowing = msg.arg1 != 0;
2551                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2552                    mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2553                }
2554            } break;
2555            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2556                synchronized (ActivityManagerService.this) {
2557                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2558                        ProcessRecord r = mLruProcesses.get(i);
2559                        if (r.thread != null) {
2560                            try {
2561                                r.thread.handleTrustStorageUpdate();
2562                            } catch (RemoteException ex) {
2563                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2564                                        r.info.processName);
2565                            }
2566                        }
2567                    }
2568                }
2569            } break;
2570            }
2571        }
2572    };
2573
2574    static final int COLLECT_PSS_BG_MSG = 1;
2575
2576    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2577        @Override
2578        public void handleMessage(Message msg) {
2579            switch (msg.what) {
2580            case COLLECT_PSS_BG_MSG: {
2581                long start = SystemClock.uptimeMillis();
2582                MemInfoReader memInfo = null;
2583                synchronized (ActivityManagerService.this) {
2584                    if (mFullPssPending) {
2585                        mFullPssPending = false;
2586                        memInfo = new MemInfoReader();
2587                    }
2588                }
2589                if (memInfo != null) {
2590                    updateCpuStatsNow();
2591                    long nativeTotalPss = 0;
2592                    final List<ProcessCpuTracker.Stats> stats;
2593                    synchronized (mProcessCpuTracker) {
2594                        stats = mProcessCpuTracker.getStats( (st)-> {
2595                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2596                        });
2597                    }
2598                    final int N = stats.size();
2599                    for (int j = 0; j < N; j++) {
2600                        synchronized (mPidsSelfLocked) {
2601                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2602                                // This is one of our own processes; skip it.
2603                                continue;
2604                            }
2605                        }
2606                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2607                    }
2608                    memInfo.readMemInfo();
2609                    synchronized (ActivityManagerService.this) {
2610                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2611                                + (SystemClock.uptimeMillis()-start) + "ms");
2612                        final long cachedKb = memInfo.getCachedSizeKb();
2613                        final long freeKb = memInfo.getFreeSizeKb();
2614                        final long zramKb = memInfo.getZramTotalSizeKb();
2615                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2616                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2617                                kernelKb*1024, nativeTotalPss*1024);
2618                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2619                                nativeTotalPss);
2620                    }
2621                }
2622
2623                int num = 0;
2624                long[] tmp = new long[3];
2625                do {
2626                    ProcessRecord proc;
2627                    int procState;
2628                    int statType;
2629                    int pid;
2630                    long lastPssTime;
2631                    synchronized (ActivityManagerService.this) {
2632                        if (mPendingPssProcesses.size() <= 0) {
2633                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2634                                    "Collected pss of " + num + " processes in "
2635                                    + (SystemClock.uptimeMillis() - start) + "ms");
2636                            mPendingPssProcesses.clear();
2637                            return;
2638                        }
2639                        proc = mPendingPssProcesses.remove(0);
2640                        procState = proc.pssProcState;
2641                        statType = proc.pssStatType;
2642                        lastPssTime = proc.lastPssTime;
2643                        long now = SystemClock.uptimeMillis();
2644                        if (proc.thread != null && procState == proc.setProcState
2645                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2646                                        < now) {
2647                            pid = proc.pid;
2648                        } else {
2649                            ProcessList.abortNextPssTime(proc.procStateMemTracker);
2650                            if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2651                                    ": still need " +
2652                                    (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE-now) +
2653                                    "ms until safe");
2654                            proc = null;
2655                            pid = 0;
2656                        }
2657                    }
2658                    if (proc != null) {
2659                        long startTime = SystemClock.currentThreadTimeMillis();
2660                        long pss = Debug.getPss(pid, tmp, null);
2661                        long endTime = SystemClock.currentThreadTimeMillis();
2662                        synchronized (ActivityManagerService.this) {
2663                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2664                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2665                                num++;
2666                                ProcessList.commitNextPssTime(proc.procStateMemTracker);
2667                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], tmp[2],
2668                                        statType, endTime-startTime, SystemClock.uptimeMillis());
2669                            } else {
2670                                ProcessList.abortNextPssTime(proc.procStateMemTracker);
2671                                if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2672                                        ": " + (proc.thread == null ? "NO_THREAD " : "") +
2673                                        (proc.pid != pid ? "PID_CHANGED " : "") +
2674                                        " initState=" + procState + " curState=" +
2675                                        proc.setProcState + " " +
2676                                        (proc.lastPssTime != lastPssTime ? "TIME_CHANGED" : ""));
2677                            }
2678                        }
2679                    }
2680                } while (true);
2681            }
2682            }
2683        }
2684    };
2685
2686    public void setSystemProcess() {
2687        try {
2688            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
2689                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
2690            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2691            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
2692                    DUMP_FLAG_PRIORITY_HIGH);
2693            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2694            ServiceManager.addService("dbinfo", new DbBinder(this));
2695            if (MONITOR_CPU_USAGE) {
2696                ServiceManager.addService("cpuinfo", new CpuBinder(this),
2697                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
2698            }
2699            ServiceManager.addService("permission", new PermissionController(this));
2700            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2701
2702            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2703                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2704            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2705
2706            synchronized (this) {
2707                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2708                app.persistent = true;
2709                app.pid = MY_PID;
2710                app.maxAdj = ProcessList.SYSTEM_ADJ;
2711                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2712                synchronized (mPidsSelfLocked) {
2713                    mPidsSelfLocked.put(app.pid, app);
2714                }
2715                updateLruProcessLocked(app, false, null);
2716                updateOomAdjLocked();
2717            }
2718        } catch (PackageManager.NameNotFoundException e) {
2719            throw new RuntimeException(
2720                    "Unable to find android system package", e);
2721        }
2722
2723        // Start watching app ops after we and the package manager are up and running.
2724        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2725                new IAppOpsCallback.Stub() {
2726                    @Override public void opChanged(int op, int uid, String packageName) {
2727                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2728                            if (mAppOpsService.checkOperation(op, uid, packageName)
2729                                    != AppOpsManager.MODE_ALLOWED) {
2730                                runInBackgroundDisabled(uid);
2731                            }
2732                        }
2733                    }
2734                });
2735    }
2736
2737    public void setWindowManager(WindowManagerService wm) {
2738        synchronized (this) {
2739            mWindowManager = wm;
2740            mStackSupervisor.setWindowManager(wm);
2741            mLockTaskController.setWindowManager(wm);
2742        }
2743    }
2744
2745    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2746        mUsageStatsService = usageStatsManager;
2747    }
2748
2749    public void startObservingNativeCrashes() {
2750        final NativeCrashListener ncl = new NativeCrashListener(this);
2751        ncl.start();
2752    }
2753
2754    public IAppOpsService getAppOpsService() {
2755        return mAppOpsService;
2756    }
2757
2758    static class MemBinder extends Binder {
2759        ActivityManagerService mActivityManagerService;
2760        private final PriorityDump.PriorityDumper mPriorityDumper =
2761                new PriorityDump.PriorityDumper() {
2762            @Override
2763            public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args,
2764                    boolean asProto) {
2765                dump(fd, pw, new String[] {"-a"}, asProto);
2766            }
2767
2768            @Override
2769            public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
2770                mActivityManagerService.dumpApplicationMemoryUsage(
2771                        fd, pw, "  ", args, false, null, asProto);
2772            }
2773        };
2774
2775        MemBinder(ActivityManagerService activityManagerService) {
2776            mActivityManagerService = activityManagerService;
2777        }
2778
2779        @Override
2780        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2781            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2782                    "meminfo", pw)) return;
2783            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2784        }
2785    }
2786
2787    static class GraphicsBinder extends Binder {
2788        ActivityManagerService mActivityManagerService;
2789        GraphicsBinder(ActivityManagerService activityManagerService) {
2790            mActivityManagerService = activityManagerService;
2791        }
2792
2793        @Override
2794        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2795            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2796                    "gfxinfo", pw)) return;
2797            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2798        }
2799    }
2800
2801    static class DbBinder extends Binder {
2802        ActivityManagerService mActivityManagerService;
2803        DbBinder(ActivityManagerService activityManagerService) {
2804            mActivityManagerService = activityManagerService;
2805        }
2806
2807        @Override
2808        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2809            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2810                    "dbinfo", pw)) return;
2811            mActivityManagerService.dumpDbInfo(fd, pw, args);
2812        }
2813    }
2814
2815    static class CpuBinder extends Binder {
2816        ActivityManagerService mActivityManagerService;
2817        private final PriorityDump.PriorityDumper mPriorityDumper =
2818                new PriorityDump.PriorityDumper() {
2819            @Override
2820            public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
2821                    boolean asProto) {
2822                if (asProto) return;
2823                if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2824                        "cpuinfo", pw)) return;
2825                synchronized (mActivityManagerService.mProcessCpuTracker) {
2826                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2827                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2828                            SystemClock.uptimeMillis()));
2829                }
2830            }
2831        };
2832
2833        CpuBinder(ActivityManagerService activityManagerService) {
2834            mActivityManagerService = activityManagerService;
2835        }
2836
2837        @Override
2838        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2839            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2840        }
2841    }
2842
2843    public static final class Lifecycle extends SystemService {
2844        private final ActivityManagerService mService;
2845
2846        public Lifecycle(Context context) {
2847            super(context);
2848            mService = new ActivityManagerService(context);
2849        }
2850
2851        @Override
2852        public void onStart() {
2853            mService.start();
2854        }
2855
2856        @Override
2857        public void onBootPhase(int phase) {
2858            if (phase == PHASE_SYSTEM_SERVICES_READY) {
2859                mService.mBatteryStatsService.systemServicesReady();
2860                mService.mServices.systemServicesReady();
2861            }
2862        }
2863
2864        @Override
2865        public void onCleanupUser(int userId) {
2866            mService.mBatteryStatsService.onCleanupUser(userId);
2867        }
2868
2869        public ActivityManagerService getService() {
2870            return mService;
2871        }
2872    }
2873
2874    /**
2875     * Encapsulates the globla setting "hidden_api_blacklist_exemptions", including tracking the
2876     * latest value via a content observer.
2877     */
2878    static class HiddenApiBlacklist extends ContentObserver {
2879
2880        private final Context mContext;
2881        private boolean mBlacklistDisabled;
2882
2883        public HiddenApiBlacklist(Handler handler, Context context) {
2884            super(handler);
2885            mContext = context;
2886        }
2887
2888        public void registerObserver() {
2889            mContext.getContentResolver().registerContentObserver(
2890                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS),
2891                    false,
2892                    this);
2893            update();
2894        }
2895
2896        private void update() {
2897            mBlacklistDisabled = "*".equals(Settings.Global.getString(mContext.getContentResolver(),
2898                    Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS));
2899        }
2900
2901        boolean isDisabled() {
2902            return mBlacklistDisabled;
2903        }
2904
2905        public void onChange(boolean selfChange) {
2906            update();
2907        }
2908    }
2909
2910    @VisibleForTesting
2911    public ActivityManagerService(Injector injector) {
2912        mInjector = injector;
2913        mContext = mInjector.getContext();
2914        mUiContext = null;
2915        GL_ES_VERSION = 0;
2916        mActivityStartController = null;
2917        mAppErrors = null;
2918        mAppWarnings = null;
2919        mAppOpsService = mInjector.getAppOpsService(null, null);
2920        mBatteryStatsService = null;
2921        mCompatModePackages = null;
2922        mConstants = null;
2923        mGrantFile = null;
2924        mHandler = null;
2925        mHandlerThread = null;
2926        mIntentFirewall = null;
2927        mKeyguardController = null;
2928        mPermissionReviewRequired = false;
2929        mProcessCpuThread = null;
2930        mProcessStats = null;
2931        mProviderMap = null;
2932        mRecentTasks = null;
2933        mServices = null;
2934        mStackSupervisor = null;
2935        mSystemThread = null;
2936        mTaskChangeNotificationController = null;
2937        mUiHandler = injector.getUiHandler(null);
2938        mUserController = null;
2939        mVrController = null;
2940        mLockTaskController = null;
2941        mLifecycleManager = null;
2942        mProcStartHandlerThread = null;
2943        mProcStartHandler = null;
2944        mHiddenApiBlacklist = null;
2945    }
2946
2947    // Note: This method is invoked on the main thread but may need to attach various
2948    // handlers to other threads.  So take care to be explicit about the looper.
2949    public ActivityManagerService(Context systemContext) {
2950        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2951        mInjector = new Injector();
2952        mContext = systemContext;
2953
2954        mFactoryTest = FactoryTest.getMode();
2955        mSystemThread = ActivityThread.currentActivityThread();
2956        mUiContext = mSystemThread.getSystemUiContext();
2957
2958        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2959
2960        mPermissionReviewRequired = mContext.getResources().getBoolean(
2961                com.android.internal.R.bool.config_permissionReviewRequired);
2962
2963        mHandlerThread = new ServiceThread(TAG,
2964                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2965        mHandlerThread.start();
2966        mHandler = new MainHandler(mHandlerThread.getLooper());
2967        mUiHandler = mInjector.getUiHandler(this);
2968
2969        mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
2970                THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
2971        mProcStartHandlerThread.start();
2972        mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
2973
2974        mConstants = new ActivityManagerConstants(this, mHandler);
2975
2976        /* static; one-time init here */
2977        if (sKillHandler == null) {
2978            sKillThread = new ServiceThread(TAG + ":kill",
2979                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2980            sKillThread.start();
2981            sKillHandler = new KillHandler(sKillThread.getLooper());
2982        }
2983
2984        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2985                "foreground", BROADCAST_FG_TIMEOUT, false);
2986        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2987                "background", BROADCAST_BG_TIMEOUT, true);
2988        mBroadcastQueues[0] = mFgBroadcastQueue;
2989        mBroadcastQueues[1] = mBgBroadcastQueue;
2990
2991        mServices = new ActiveServices(this);
2992        mProviderMap = new ProviderMap(this);
2993        mAppErrors = new AppErrors(mUiContext, this);
2994
2995        File dataDir = Environment.getDataDirectory();
2996        File systemDir = new File(dataDir, "system");
2997        systemDir.mkdirs();
2998
2999        mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
3000
3001        // TODO: Move creation of battery stats service outside of activity manager service.
3002        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
3003        mBatteryStatsService.getActiveStatistics().readLocked();
3004        mBatteryStatsService.scheduleWriteToDisk();
3005        mOnBattery = DEBUG_POWER ? true
3006                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
3007        mBatteryStatsService.getActiveStatistics().setCallback(this);
3008
3009        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
3010
3011        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
3012
3013        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
3014
3015        mUserController = new UserController(this);
3016
3017        mVrController = new VrController(this);
3018
3019        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
3020            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
3021
3022        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
3023            mUseFifoUiScheduling = true;
3024        }
3025
3026        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
3027        mTempConfig.setToDefaults();
3028        mTempConfig.setLocales(LocaleList.getDefault());
3029        mConfigurationSeq = mTempConfig.seq = 1;
3030        mStackSupervisor = createStackSupervisor();
3031        mStackSupervisor.onConfigurationChanged(mTempConfig);
3032        mKeyguardController = mStackSupervisor.getKeyguardController();
3033        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
3034        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
3035        mTaskChangeNotificationController =
3036                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
3037        mActivityStartController = new ActivityStartController(this);
3038        mRecentTasks = createRecentTasks();
3039        mStackSupervisor.setRecentTasks(mRecentTasks);
3040        mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
3041        mLifecycleManager = new ClientLifecycleManager();
3042
3043        mProcessCpuThread = new Thread("CpuTracker") {
3044            @Override
3045            public void run() {
3046                synchronized (mProcessCpuTracker) {
3047                    mProcessCpuInitLatch.countDown();
3048                    mProcessCpuTracker.init();
3049                }
3050                while (true) {
3051                    try {
3052                        try {
3053                            synchronized(this) {
3054                                final long now = SystemClock.uptimeMillis();
3055                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
3056                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
3057                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
3058                                //        + ", write delay=" + nextWriteDelay);
3059                                if (nextWriteDelay < nextCpuDelay) {
3060                                    nextCpuDelay = nextWriteDelay;
3061                                }
3062                                if (nextCpuDelay > 0) {
3063                                    mProcessCpuMutexFree.set(true);
3064                                    this.wait(nextCpuDelay);
3065                                }
3066                            }
3067                        } catch (InterruptedException e) {
3068                        }
3069                        updateCpuStatsNow();
3070                    } catch (Exception e) {
3071                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
3072                    }
3073                }
3074            }
3075        };
3076
3077        mHiddenApiBlacklist = new HiddenApiBlacklist(mHandler, mContext);
3078
3079        Watchdog.getInstance().addMonitor(this);
3080        Watchdog.getInstance().addThread(mHandler);
3081
3082        // bind background thread to little cores
3083        // this is expected to fail inside of framework tests because apps can't touch cpusets directly
3084        try {
3085            Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(),
3086                    Process.THREAD_GROUP_BG_NONINTERACTIVE);
3087        } catch (Exception e) {
3088            Slog.w(TAG, "Setting background thread cpuset failed");
3089        }
3090
3091    }
3092
3093    protected ActivityStackSupervisor createStackSupervisor() {
3094        final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
3095        supervisor.initialize();
3096        return supervisor;
3097    }
3098
3099    protected RecentTasks createRecentTasks() {
3100        return new RecentTasks(this, mStackSupervisor);
3101    }
3102
3103    RecentTasks getRecentTasks() {
3104        return mRecentTasks;
3105    }
3106
3107    public void setSystemServiceManager(SystemServiceManager mgr) {
3108        mSystemServiceManager = mgr;
3109    }
3110
3111    public void setInstaller(Installer installer) {
3112        mInstaller = installer;
3113    }
3114
3115    private void start() {
3116        removeAllProcessGroups();
3117        mProcessCpuThread.start();
3118
3119        mBatteryStatsService.publish();
3120        mAppOpsService.publish(mContext);
3121        Slog.d("AppOps", "AppOpsService published");
3122        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
3123        // Wait for the synchronized block started in mProcessCpuThread,
3124        // so that any other acccess to mProcessCpuTracker from main thread
3125        // will be blocked during mProcessCpuTracker initialization.
3126        try {
3127            mProcessCpuInitLatch.await();
3128        } catch (InterruptedException e) {
3129            Slog.wtf(TAG, "Interrupted wait during start", e);
3130            Thread.currentThread().interrupt();
3131            throw new IllegalStateException("Interrupted wait during start");
3132        }
3133    }
3134
3135    void onUserStoppedLocked(int userId) {
3136        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
3137        mAllowAppSwitchUids.remove(userId);
3138    }
3139
3140    public void initPowerManagement() {
3141        mStackSupervisor.initPowerManagement();
3142        mBatteryStatsService.initPowerManagement();
3143        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
3144        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
3145        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
3146        mVoiceWakeLock.setReferenceCounted(false);
3147    }
3148
3149    private ArraySet<String> getBackgroundLaunchBroadcasts() {
3150        if (mBackgroundLaunchBroadcasts == null) {
3151            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
3152        }
3153        return mBackgroundLaunchBroadcasts;
3154    }
3155
3156    @Override
3157    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3158            throws RemoteException {
3159        if (code == SYSPROPS_TRANSACTION) {
3160            // We need to tell all apps about the system property change.
3161            ArrayList<IBinder> procs = new ArrayList<IBinder>();
3162            synchronized(this) {
3163                final int NP = mProcessNames.getMap().size();
3164                for (int ip=0; ip<NP; ip++) {
3165                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
3166                    final int NA = apps.size();
3167                    for (int ia=0; ia<NA; ia++) {
3168                        ProcessRecord app = apps.valueAt(ia);
3169                        if (app.thread != null) {
3170                            procs.add(app.thread.asBinder());
3171                        }
3172                    }
3173                }
3174            }
3175
3176            int N = procs.size();
3177            for (int i=0; i<N; i++) {
3178                Parcel data2 = Parcel.obtain();
3179                try {
3180                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
3181                            Binder.FLAG_ONEWAY);
3182                } catch (RemoteException e) {
3183                }
3184                data2.recycle();
3185            }
3186        }
3187        try {
3188            return super.onTransact(code, data, reply, flags);
3189        } catch (RuntimeException e) {
3190            // The activity manager only throws certain exceptions intentionally, so let's
3191            // log all others.
3192            if (!(e instanceof SecurityException
3193                    || e instanceof IllegalArgumentException
3194                    || e instanceof IllegalStateException)) {
3195                Slog.wtf(TAG, "Activity Manager Crash."
3196                        + " UID:" + Binder.getCallingUid()
3197                        + " PID:" + Binder.getCallingPid()
3198                        + " TRANS:" + code, e);
3199            }
3200            throw e;
3201        }
3202    }
3203
3204    void updateCpuStats() {
3205        final long now = SystemClock.uptimeMillis();
3206        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
3207            return;
3208        }
3209        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
3210            synchronized (mProcessCpuThread) {
3211                mProcessCpuThread.notify();
3212            }
3213        }
3214    }
3215
3216    void updateCpuStatsNow() {
3217        synchronized (mProcessCpuTracker) {
3218            mProcessCpuMutexFree.set(false);
3219            final long now = SystemClock.uptimeMillis();
3220            boolean haveNewCpuStats = false;
3221
3222            if (MONITOR_CPU_USAGE &&
3223                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
3224                mLastCpuTime.set(now);
3225                mProcessCpuTracker.update();
3226                if (mProcessCpuTracker.hasGoodLastStats()) {
3227                    haveNewCpuStats = true;
3228                    //Slog.i(TAG, mProcessCpu.printCurrentState());
3229                    //Slog.i(TAG, "Total CPU usage: "
3230                    //        + mProcessCpu.getTotalCpuPercent() + "%");
3231
3232                    // Slog the cpu usage if the property is set.
3233                    if ("true".equals(SystemProperties.get("events.cpu"))) {
3234                        int user = mProcessCpuTracker.getLastUserTime();
3235                        int system = mProcessCpuTracker.getLastSystemTime();
3236                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
3237                        int irq = mProcessCpuTracker.getLastIrqTime();
3238                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
3239                        int idle = mProcessCpuTracker.getLastIdleTime();
3240
3241                        int total = user + system + iowait + irq + softIrq + idle;
3242                        if (total == 0) total = 1;
3243
3244                        EventLog.writeEvent(EventLogTags.CPU,
3245                                ((user+system+iowait+irq+softIrq) * 100) / total,
3246                                (user * 100) / total,
3247                                (system * 100) / total,
3248                                (iowait * 100) / total,
3249                                (irq * 100) / total,
3250                                (softIrq * 100) / total);
3251                    }
3252                }
3253            }
3254
3255            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3256            synchronized(bstats) {
3257                synchronized(mPidsSelfLocked) {
3258                    if (haveNewCpuStats) {
3259                        if (bstats.startAddingCpuLocked()) {
3260                            int totalUTime = 0;
3261                            int totalSTime = 0;
3262                            final int N = mProcessCpuTracker.countStats();
3263                            for (int i=0; i<N; i++) {
3264                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3265                                if (!st.working) {
3266                                    continue;
3267                                }
3268                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3269                                totalUTime += st.rel_utime;
3270                                totalSTime += st.rel_stime;
3271                                if (pr != null) {
3272                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3273                                    if (ps == null || !ps.isActive()) {
3274                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3275                                                pr.info.uid, pr.processName);
3276                                    }
3277                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3278                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3279                                    if (pr.lastCpuTime == 0) {
3280                                        pr.lastCpuTime = pr.curCpuTime;
3281                                    }
3282                                } else {
3283                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3284                                    if (ps == null || !ps.isActive()) {
3285                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3286                                                bstats.mapUid(st.uid), st.name);
3287                                    }
3288                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3289                                }
3290                            }
3291                            final int userTime = mProcessCpuTracker.getLastUserTime();
3292                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3293                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3294                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3295                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3296                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3297                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3298                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3299                        }
3300                    }
3301                }
3302
3303                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3304                    mLastWriteTime = now;
3305                    mBatteryStatsService.scheduleWriteToDisk();
3306                }
3307            }
3308        }
3309    }
3310
3311    @Override
3312    public void batteryNeedsCpuUpdate() {
3313        updateCpuStatsNow();
3314    }
3315
3316    @Override
3317    public void batteryPowerChanged(boolean onBattery) {
3318        // When plugging in, update the CPU stats first before changing
3319        // the plug state.
3320        updateCpuStatsNow();
3321        synchronized (this) {
3322            synchronized(mPidsSelfLocked) {
3323                mOnBattery = DEBUG_POWER ? true : onBattery;
3324            }
3325        }
3326    }
3327
3328    @Override
3329    public void batterySendBroadcast(Intent intent) {
3330        synchronized (this) {
3331            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3332                    OP_NONE, null, false, false,
3333                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3334        }
3335    }
3336
3337    /**
3338     * Initialize the application bind args. These are passed to each
3339     * process when the bindApplication() IPC is sent to the process. They're
3340     * lazily setup to make sure the services are running when they're asked for.
3341     */
3342    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3343        // Isolated processes won't get this optimization, so that we don't
3344        // violate the rules about which services they have access to.
3345        if (isolated) {
3346            if (mIsolatedAppBindArgs == null) {
3347                mIsolatedAppBindArgs = new HashMap<>();
3348                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3349            }
3350            return mIsolatedAppBindArgs;
3351        }
3352
3353        if (mAppBindArgs == null) {
3354            mAppBindArgs = new HashMap<>();
3355
3356            // Setup the application init args
3357            mAppBindArgs.put("package", ServiceManager.getService("package"));
3358            mAppBindArgs.put("window", ServiceManager.getService("window"));
3359            mAppBindArgs.put(Context.ALARM_SERVICE,
3360                    ServiceManager.getService(Context.ALARM_SERVICE));
3361        }
3362        return mAppBindArgs;
3363    }
3364
3365    /**
3366     * Update AMS states when an activity is resumed. This should only be called by
3367     * {@link ActivityStack#onActivityStateChanged(ActivityRecord, ActivityState, String)} when an
3368     * activity is resumed.
3369     */
3370    @GuardedBy("this")
3371    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3372        final TaskRecord task = r.getTask();
3373        if (task.isActivityTypeStandard()) {
3374            if (mCurAppTimeTracker != r.appTimeTracker) {
3375                // We are switching app tracking.  Complete the current one.
3376                if (mCurAppTimeTracker != null) {
3377                    mCurAppTimeTracker.stop();
3378                    mHandler.obtainMessage(
3379                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3380                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3381                    mCurAppTimeTracker = null;
3382                }
3383                if (r.appTimeTracker != null) {
3384                    mCurAppTimeTracker = r.appTimeTracker;
3385                    startTimeTrackingFocusedActivityLocked();
3386                }
3387            } else {
3388                startTimeTrackingFocusedActivityLocked();
3389            }
3390        } else {
3391            r.appTimeTracker = null;
3392        }
3393        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3394        // TODO: Probably not, because we don't want to resume voice on switching
3395        // back to this activity
3396        if (task.voiceInteractor != null) {
3397            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3398        } else {
3399            finishRunningVoiceLocked();
3400
3401            if (mLastResumedActivity != null) {
3402                final IVoiceInteractionSession session;
3403
3404                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3405                if (lastResumedActivityTask != null
3406                        && lastResumedActivityTask.voiceSession != null) {
3407                    session = lastResumedActivityTask.voiceSession;
3408                } else {
3409                    session = mLastResumedActivity.voiceSession;
3410                }
3411
3412                if (session != null) {
3413                    // We had been in a voice interaction session, but now focused has
3414                    // move to something different.  Just finish the session, we can't
3415                    // return to it and retain the proper state and synchronization with
3416                    // the voice interaction service.
3417                    finishVoiceTask(session);
3418                }
3419            }
3420        }
3421
3422        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3423            mUserController.sendForegroundProfileChanged(r.userId);
3424        }
3425        mLastResumedActivity = r;
3426
3427        mWindowManager.setFocusedApp(r.appToken, true);
3428
3429        applyUpdateLockStateLocked(r);
3430        applyUpdateVrModeLocked(r);
3431
3432        EventLogTags.writeAmSetResumedActivity(
3433                r == null ? -1 : r.userId,
3434                r == null ? "NULL" : r.shortComponentName,
3435                reason);
3436    }
3437
3438    @Override
3439    public void setFocusedStack(int stackId) {
3440        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3441        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3442        final long callingId = Binder.clearCallingIdentity();
3443        try {
3444            synchronized (this) {
3445                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3446                if (stack == null) {
3447                    Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
3448                    return;
3449                }
3450                final ActivityRecord r = stack.topRunningActivityLocked();
3451                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3452                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3453                }
3454            }
3455        } finally {
3456            Binder.restoreCallingIdentity(callingId);
3457        }
3458    }
3459
3460    @Override
3461    public void setFocusedTask(int taskId) {
3462        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3463        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3464        final long callingId = Binder.clearCallingIdentity();
3465        try {
3466            synchronized (this) {
3467                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3468                if (task == null) {
3469                    return;
3470                }
3471                final ActivityRecord r = task.topRunningActivityLocked();
3472                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3473                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3474                }
3475            }
3476        } finally {
3477            Binder.restoreCallingIdentity(callingId);
3478        }
3479    }
3480
3481    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3482    @Override
3483    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3484        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3485                "registerTaskStackListener()");
3486        mTaskChangeNotificationController.registerTaskStackListener(listener);
3487    }
3488
3489    /**
3490     * Unregister a task stack listener so that it stops receiving callbacks.
3491     */
3492    @Override
3493    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3494        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3495                "unregisterTaskStackListener()");
3496         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3497     }
3498
3499    @Override
3500    public void notifyActivityDrawn(IBinder token) {
3501        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3502        synchronized (this) {
3503            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3504            if (r != null) {
3505                r.getStack().notifyActivityDrawnLocked(r);
3506            }
3507        }
3508    }
3509
3510    final void applyUpdateLockStateLocked(ActivityRecord r) {
3511        // Modifications to the UpdateLock state are done on our handler, outside
3512        // the activity manager's locks.  The new state is determined based on the
3513        // state *now* of the relevant activity record.  The object is passed to
3514        // the handler solely for logging detail, not to be consulted/modified.
3515        final boolean nextState = r != null && r.immersive;
3516        mHandler.sendMessage(
3517                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3518    }
3519
3520    final void applyUpdateVrModeLocked(ActivityRecord r) {
3521        // VR apps are expected to run in a main display. If an app is turning on VR for
3522        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3523        // fullscreen stack before enabling VR Mode.
3524        // TODO: The goal of this code is to keep the VR app on the main display. When the
3525        // stack implementation changes in the future, keep in mind that the use of the fullscreen
3526        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3527        // option would be a better choice here.
3528        if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3529            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3530                    + " to main stack for VR");
3531            final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3532                    WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3533            moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3534        }
3535        mHandler.sendMessage(
3536                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3537    }
3538
3539    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3540        Message msg = Message.obtain();
3541        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3542        msg.obj = r.getTask().askedCompatMode ? null : r;
3543        mUiHandler.sendMessage(msg);
3544    }
3545
3546    final AppWarnings getAppWarningsLocked() {
3547        return mAppWarnings;
3548    }
3549
3550    /**
3551     * Shows app warning dialogs, if necessary.
3552     *
3553     * @param r activity record for which the warnings may be displayed
3554     */
3555    final void showAppWarningsIfNeededLocked(ActivityRecord r) {
3556        mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
3557        mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
3558        mAppWarnings.showDeprecatedTargetDialogIfNeeded(r);
3559    }
3560
3561    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3562            String what, Object obj, ProcessRecord srcApp) {
3563        app.lastActivityTime = now;
3564
3565        if (app.activities.size() > 0 || app.recentTasks.size() > 0) {
3566            // Don't want to touch dependent processes that are hosting activities.
3567            return index;
3568        }
3569
3570        int lrui = mLruProcesses.lastIndexOf(app);
3571        if (lrui < 0) {
3572            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3573                    + what + " " + obj + " from " + srcApp);
3574            return index;
3575        }
3576
3577        if (lrui >= index) {
3578            // Don't want to cause this to move dependent processes *back* in the
3579            // list as if they were less frequently used.
3580            return index;
3581        }
3582
3583        if (lrui >= mLruProcessActivityStart) {
3584            // Don't want to touch dependent processes that are hosting activities.
3585            return index;
3586        }
3587
3588        mLruProcesses.remove(lrui);
3589        if (index > 0) {
3590            index--;
3591        }
3592        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3593                + " in LRU list: " + app);
3594        mLruProcesses.add(index, app);
3595        return index;
3596    }
3597
3598    static void killProcessGroup(int uid, int pid) {
3599        if (sKillHandler != null) {
3600            sKillHandler.sendMessage(
3601                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3602        } else {
3603            Slog.w(TAG, "Asked to kill process group before system bringup!");
3604            Process.killProcessGroup(uid, pid);
3605        }
3606    }
3607
3608    final void removeLruProcessLocked(ProcessRecord app) {
3609        int lrui = mLruProcesses.lastIndexOf(app);
3610        if (lrui >= 0) {
3611            if (!app.killed) {
3612                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3613                if (app.pid > 0) {
3614                    killProcessQuiet(app.pid);
3615                    killProcessGroup(app.uid, app.pid);
3616                } else {
3617                    app.pendingStart = false;
3618                }
3619            }
3620            if (lrui <= mLruProcessActivityStart) {
3621                mLruProcessActivityStart--;
3622            }
3623            if (lrui <= mLruProcessServiceStart) {
3624                mLruProcessServiceStart--;
3625            }
3626            mLruProcesses.remove(lrui);
3627        }
3628    }
3629
3630    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3631            ProcessRecord client) {
3632        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3633                || app.treatLikeActivity || app.recentTasks.size() > 0;
3634        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3635        if (!activityChange && hasActivity) {
3636            // The process has activities, so we are only allowing activity-based adjustments
3637            // to move it.  It should be kept in the front of the list with other
3638            // processes that have activities, and we don't want those to change their
3639            // order except due to activity operations.
3640            return;
3641        }
3642
3643        mLruSeq++;
3644        final long now = SystemClock.uptimeMillis();
3645        app.lastActivityTime = now;
3646
3647        // First a quick reject: if the app is already at the position we will
3648        // put it, then there is nothing to do.
3649        if (hasActivity) {
3650            final int N = mLruProcesses.size();
3651            if (N > 0 && mLruProcesses.get(N-1) == app) {
3652                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3653                return;
3654            }
3655        } else {
3656            if (mLruProcessServiceStart > 0
3657                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3658                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3659                return;
3660            }
3661        }
3662
3663        int lrui = mLruProcesses.lastIndexOf(app);
3664
3665        if (app.persistent && lrui >= 0) {
3666            // We don't care about the position of persistent processes, as long as
3667            // they are in the list.
3668            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3669            return;
3670        }
3671
3672        /* In progress: compute new position first, so we can avoid doing work
3673           if the process is not actually going to move.  Not yet working.
3674        int addIndex;
3675        int nextIndex;
3676        boolean inActivity = false, inService = false;
3677        if (hasActivity) {
3678            // Process has activities, put it at the very tipsy-top.
3679            addIndex = mLruProcesses.size();
3680            nextIndex = mLruProcessServiceStart;
3681            inActivity = true;
3682        } else if (hasService) {
3683            // Process has services, put it at the top of the service list.
3684            addIndex = mLruProcessActivityStart;
3685            nextIndex = mLruProcessServiceStart;
3686            inActivity = true;
3687            inService = true;
3688        } else  {
3689            // Process not otherwise of interest, it goes to the top of the non-service area.
3690            addIndex = mLruProcessServiceStart;
3691            if (client != null) {
3692                int clientIndex = mLruProcesses.lastIndexOf(client);
3693                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3694                        + app);
3695                if (clientIndex >= 0 && addIndex > clientIndex) {
3696                    addIndex = clientIndex;
3697                }
3698            }
3699            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3700        }
3701
3702        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3703                + mLruProcessActivityStart + "): " + app);
3704        */
3705
3706        if (lrui >= 0) {
3707            if (lrui < mLruProcessActivityStart) {
3708                mLruProcessActivityStart--;
3709            }
3710            if (lrui < mLruProcessServiceStart) {
3711                mLruProcessServiceStart--;
3712            }
3713            /*
3714            if (addIndex > lrui) {
3715                addIndex--;
3716            }
3717            if (nextIndex > lrui) {
3718                nextIndex--;
3719            }
3720            */
3721            mLruProcesses.remove(lrui);
3722        }
3723
3724        /*
3725        mLruProcesses.add(addIndex, app);
3726        if (inActivity) {
3727            mLruProcessActivityStart++;
3728        }
3729        if (inService) {
3730            mLruProcessActivityStart++;
3731        }
3732        */
3733
3734        int nextIndex;
3735        if (hasActivity) {
3736            final int N = mLruProcesses.size();
3737            if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
3738                    && mLruProcessActivityStart < (N - 1)) {
3739                // Process doesn't have activities, but has clients with
3740                // activities...  move it up, but one below the top (the top
3741                // should always have a real activity).
3742                if (DEBUG_LRU) Slog.d(TAG_LRU,
3743                        "Adding to second-top of LRU activity list: " + app);
3744                mLruProcesses.add(N - 1, app);
3745                // To keep it from spamming the LRU list (by making a bunch of clients),
3746                // we will push down any other entries owned by the app.
3747                final int uid = app.info.uid;
3748                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3749                    ProcessRecord subProc = mLruProcesses.get(i);
3750                    if (subProc.info.uid == uid) {
3751                        // We want to push this one down the list.  If the process after
3752                        // it is for the same uid, however, don't do so, because we don't
3753                        // want them internally to be re-ordered.
3754                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3755                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3756                                    "Pushing uid " + uid + " swapping at " + i + ": "
3757                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3758                            ProcessRecord tmp = mLruProcesses.get(i);
3759                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3760                            mLruProcesses.set(i - 1, tmp);
3761                            i--;
3762                        }
3763                    } else {
3764                        // A gap, we can stop here.
3765                        break;
3766                    }
3767                }
3768            } else {
3769                // Process has activities, put it at the very tipsy-top.
3770                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3771                mLruProcesses.add(app);
3772            }
3773            nextIndex = mLruProcessServiceStart;
3774        } else if (hasService) {
3775            // Process has services, put it at the top of the service list.
3776            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3777            mLruProcesses.add(mLruProcessActivityStart, app);
3778            nextIndex = mLruProcessServiceStart;
3779            mLruProcessActivityStart++;
3780        } else  {
3781            // Process not otherwise of interest, it goes to the top of the non-service area.
3782            int index = mLruProcessServiceStart;
3783            if (client != null) {
3784                // If there is a client, don't allow the process to be moved up higher
3785                // in the list than that client.
3786                int clientIndex = mLruProcesses.lastIndexOf(client);
3787                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3788                        + " when updating " + app);
3789                if (clientIndex <= lrui) {
3790                    // Don't allow the client index restriction to push it down farther in the
3791                    // list than it already is.
3792                    clientIndex = lrui;
3793                }
3794                if (clientIndex >= 0 && index > clientIndex) {
3795                    index = clientIndex;
3796                }
3797            }
3798            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3799            mLruProcesses.add(index, app);
3800            nextIndex = index-1;
3801            mLruProcessActivityStart++;
3802            mLruProcessServiceStart++;
3803        }
3804
3805        // If the app is currently using a content provider or service,
3806        // bump those processes as well.
3807        for (int j=app.connections.size()-1; j>=0; j--) {
3808            ConnectionRecord cr = app.connections.valueAt(j);
3809            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3810                    && cr.binding.service.app != null
3811                    && cr.binding.service.app.lruSeq != mLruSeq
3812                    && !cr.binding.service.app.persistent) {
3813                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3814                        "service connection", cr, app);
3815            }
3816        }
3817        for (int j=app.conProviders.size()-1; j>=0; j--) {
3818            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3819            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3820                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3821                        "provider reference", cpr, app);
3822            }
3823        }
3824    }
3825
3826    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3827        if (uid == SYSTEM_UID) {
3828            // The system gets to run in any process.  If there are multiple
3829            // processes with the same uid, just pick the first (this
3830            // should never happen).
3831            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3832            if (procs == null) return null;
3833            final int procCount = procs.size();
3834            for (int i = 0; i < procCount; i++) {
3835                final int procUid = procs.keyAt(i);
3836                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3837                    // Don't use an app process or different user process for system component.
3838                    continue;
3839                }
3840                return procs.valueAt(i);
3841            }
3842        }
3843        ProcessRecord proc = mProcessNames.get(processName, uid);
3844        if (false && proc != null && !keepIfLarge
3845                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3846                && proc.lastCachedPss >= 4000) {
3847            // Turn this condition on to cause killing to happen regularly, for testing.
3848            if (proc.baseProcessTracker != null) {
3849                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3850            }
3851            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3852        } else if (proc != null && !keepIfLarge
3853                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3854                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3855            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3856            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3857                if (proc.baseProcessTracker != null) {
3858                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3859                }
3860                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3861            }
3862        }
3863        return proc;
3864    }
3865
3866    void notifyPackageUse(String packageName, int reason) {
3867        synchronized(this) {
3868            getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3869        }
3870    }
3871
3872    boolean isNextTransitionForward() {
3873        int transit = mWindowManager.getPendingAppTransition();
3874        return transit == TRANSIT_ACTIVITY_OPEN
3875                || transit == TRANSIT_TASK_OPEN
3876                || transit == TRANSIT_TASK_TO_FRONT;
3877    }
3878
3879    boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3880            String processName, String abiOverride, int uid, Runnable crashHandler) {
3881        synchronized(this) {
3882            ApplicationInfo info = new ApplicationInfo();
3883            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3884            // For isolated processes, the former contains the parent's uid and the latter the
3885            // actual uid of the isolated process.
3886            // In the special case introduced by this method (which is, starting an isolated
3887            // process directly from the SystemServer without an actual parent app process) the
3888            // closest thing to a parent's uid is SYSTEM_UID.
3889            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3890            // the |isolated| logic in the ProcessRecord constructor.
3891            info.uid = SYSTEM_UID;
3892            info.processName = processName;
3893            info.className = entryPoint;
3894            info.packageName = "android";
3895            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3896            info.targetSdkVersion = Build.VERSION.SDK_INT;
3897            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3898                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3899                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3900                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3901                    crashHandler);
3902            return proc != null;
3903        }
3904    }
3905
3906    @GuardedBy("this")
3907    final ProcessRecord startProcessLocked(String processName,
3908            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3909            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3910            boolean isolated, boolean keepIfLarge) {
3911        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3912                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3913                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3914                null /* crashHandler */);
3915    }
3916
3917    @GuardedBy("this")
3918    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3919            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3920            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3921            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3922        long startTime = SystemClock.elapsedRealtime();
3923        ProcessRecord app;
3924        if (!isolated) {
3925            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3926            checkTime(startTime, "startProcess: after getProcessRecord");
3927
3928            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3929                // If we are in the background, then check to see if this process
3930                // is bad.  If so, we will just silently fail.
3931                if (mAppErrors.isBadProcessLocked(info)) {
3932                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3933                            + "/" + info.processName);
3934                    return null;
3935                }
3936            } else {
3937                // When the user is explicitly starting a process, then clear its
3938                // crash count so that we won't make it bad until they see at
3939                // least one crash dialog again, and make the process good again
3940                // if it had been bad.
3941                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3942                        + "/" + info.processName);
3943                mAppErrors.resetProcessCrashTimeLocked(info);
3944                if (mAppErrors.isBadProcessLocked(info)) {
3945                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3946                            UserHandle.getUserId(info.uid), info.uid,
3947                            info.processName);
3948                    mAppErrors.clearBadProcessLocked(info);
3949                    if (app != null) {
3950                        app.bad = false;
3951                    }
3952                }
3953            }
3954        } else {
3955            // If this is an isolated process, it can't re-use an existing process.
3956            app = null;
3957        }
3958
3959        // We don't have to do anything more if:
3960        // (1) There is an existing application record; and
3961        // (2) The caller doesn't think it is dead, OR there is no thread
3962        //     object attached to it so we know it couldn't have crashed; and
3963        // (3) There is a pid assigned to it, so it is either starting or
3964        //     already running.
3965        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3966                + " app=" + app + " knownToBeDead=" + knownToBeDead
3967                + " thread=" + (app != null ? app.thread : null)
3968                + " pid=" + (app != null ? app.pid : -1));
3969        if (app != null && app.pid > 0) {
3970            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3971                // We already have the app running, or are waiting for it to
3972                // come up (we have a pid but not yet its thread), so keep it.
3973                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3974                // If this is a new package in the process, add the package to the list
3975                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3976                checkTime(startTime, "startProcess: done, added package to proc");
3977                return app;
3978            }
3979
3980            // An application record is attached to a previous process,
3981            // clean it up now.
3982            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3983            checkTime(startTime, "startProcess: bad proc running, killing");
3984            killProcessGroup(app.uid, app.pid);
3985            handleAppDiedLocked(app, true, true);
3986            checkTime(startTime, "startProcess: done killing old proc");
3987        }
3988
3989        String hostingNameStr = hostingName != null
3990                ? hostingName.flattenToShortString() : null;
3991
3992        if (app == null) {
3993            checkTime(startTime, "startProcess: creating new process record");
3994            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3995            if (app == null) {
3996                Slog.w(TAG, "Failed making new process record for "
3997                        + processName + "/" + info.uid + " isolated=" + isolated);
3998                return null;
3999            }
4000            app.crashHandler = crashHandler;
4001            app.isolatedEntryPoint = entryPoint;
4002            app.isolatedEntryPointArgs = entryPointArgs;
4003            checkTime(startTime, "startProcess: done creating new process record");
4004        } else {
4005            // If this is a new package in the process, add the package to the list
4006            app.addPackage(info.packageName, info.versionCode, mProcessStats);
4007            checkTime(startTime, "startProcess: added package to existing proc");
4008        }
4009
4010        // If the system is not ready yet, then hold off on starting this
4011        // process until it is.
4012        if (!mProcessesReady
4013                && !isAllowedWhileBooting(info)
4014                && !allowWhileBooting) {
4015            if (!mProcessesOnHold.contains(app)) {
4016                mProcessesOnHold.add(app);
4017            }
4018            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
4019                    "System not ready, putting on hold: " + app);
4020            checkTime(startTime, "startProcess: returning with proc on hold");
4021            return app;
4022        }
4023
4024        checkTime(startTime, "startProcess: stepping in to startProcess");
4025        final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
4026        checkTime(startTime, "startProcess: done starting proc!");
4027        return success ? app : null;
4028    }
4029
4030    boolean isAllowedWhileBooting(ApplicationInfo ai) {
4031        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
4032    }
4033
4034    @GuardedBy("this")
4035    private final void startProcessLocked(ProcessRecord app,
4036            String hostingType, String hostingNameStr) {
4037        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
4038    }
4039
4040    @GuardedBy("this")
4041    private final boolean startProcessLocked(ProcessRecord app,
4042            String hostingType, String hostingNameStr, String abiOverride) {
4043        return startProcessLocked(app, hostingType, hostingNameStr,
4044                false /* disableHiddenApiChecks */, abiOverride);
4045    }
4046
4047    /**
4048     * @return {@code true} if process start is successful, false otherwise.
4049     */
4050    @GuardedBy("this")
4051    private final boolean startProcessLocked(ProcessRecord app, String hostingType,
4052            String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
4053        if (app.pendingStart) {
4054            return true;
4055        }
4056        long startTime = SystemClock.elapsedRealtime();
4057        if (app.pid > 0 && app.pid != MY_PID) {
4058            checkTime(startTime, "startProcess: removing from pids map");
4059            synchronized (mPidsSelfLocked) {
4060                mPidsSelfLocked.remove(app.pid);
4061                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4062            }
4063            checkTime(startTime, "startProcess: done removing from pids map");
4064            app.setPid(0);
4065        }
4066
4067        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
4068                "startProcessLocked removing on hold: " + app);
4069        mProcessesOnHold.remove(app);
4070
4071        checkTime(startTime, "startProcess: starting to update cpu stats");
4072        updateCpuStats();
4073        checkTime(startTime, "startProcess: done updating cpu stats");
4074
4075        try {
4076            try {
4077                final int userId = UserHandle.getUserId(app.uid);
4078                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
4079            } catch (RemoteException e) {
4080                throw e.rethrowAsRuntimeException();
4081            }
4082
4083            int uid = app.uid;
4084            int[] gids = null;
4085            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
4086            if (!app.isolated) {
4087                int[] permGids = null;
4088                try {
4089                    checkTime(startTime, "startProcess: getting gids from package manager");
4090                    final IPackageManager pm = AppGlobals.getPackageManager();
4091                    permGids = pm.getPackageGids(app.info.packageName,
4092                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
4093                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
4094                            StorageManagerInternal.class);
4095                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
4096                            app.info.packageName);
4097                } catch (RemoteException e) {
4098                    throw e.rethrowAsRuntimeException();
4099                }
4100
4101                /*
4102                 * Add shared application and profile GIDs so applications can share some
4103                 * resources like shared libraries and access user-wide resources
4104                 */
4105                if (ArrayUtils.isEmpty(permGids)) {
4106                    gids = new int[3];
4107                } else {
4108                    gids = new int[permGids.length + 3];
4109                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
4110                }
4111                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
4112                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
4113                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
4114
4115                // Replace any invalid GIDs
4116                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
4117                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
4118            }
4119            checkTime(startTime, "startProcess: building args");
4120            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
4121                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4122                        && mTopComponent != null
4123                        && app.processName.equals(mTopComponent.getPackageName())) {
4124                    uid = 0;
4125                }
4126                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
4127                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
4128                    uid = 0;
4129                }
4130            }
4131            int runtimeFlags = 0;
4132            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4133                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
4134                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
4135                // Also turn on CheckJNI for debuggable apps. It's quite
4136                // awkward to turn on otherwise.
4137                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4138            }
4139            // Run the app in safe mode if its manifest requests so or the
4140            // system is booted in safe mode.
4141            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
4142                mSafeMode == true) {
4143                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
4144            }
4145            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
4146                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4147            }
4148            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
4149            if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
4150                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
4151            }
4152            String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
4153            if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
4154                runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
4155            }
4156            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
4157                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
4158            }
4159            if ("1".equals(SystemProperties.get("debug.assert"))) {
4160                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
4161            }
4162            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
4163                // Enable all debug flags required by the native debugger.
4164                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
4165                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
4166                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
4167                mNativeDebuggingApp = null;
4168            }
4169
4170            if (app.info.isPrivilegedApp() &&
4171                    SystemProperties.getBoolean("pm.dexopt.priv-apps-oob", false)) {
4172                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
4173            }
4174
4175            if (!app.info.isAllowedToUseHiddenApi() &&
4176                    !disableHiddenApiChecks &&
4177                    !mHiddenApiBlacklist.isDisabled()) {
4178                // This app is not allowed to use undocumented and private APIs, or blacklisting is
4179                // enabled. Set up its runtime with the appropriate flag.
4180                runtimeFlags |= Zygote.ENABLE_HIDDEN_API_CHECKS;
4181            }
4182
4183            String invokeWith = null;
4184            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4185                // Debuggable apps may include a wrapper script with their library directory.
4186                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
4187                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4188                try {
4189                    if (new File(wrapperFileName).exists()) {
4190                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
4191                    }
4192                } finally {
4193                    StrictMode.setThreadPolicy(oldPolicy);
4194                }
4195            }
4196
4197            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
4198            if (requiredAbi == null) {
4199                requiredAbi = Build.SUPPORTED_ABIS[0];
4200            }
4201
4202            String instructionSet = null;
4203            if (app.info.primaryCpuAbi != null) {
4204                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
4205            }
4206
4207            app.gids = gids;
4208            app.requiredAbi = requiredAbi;
4209            app.instructionSet = instructionSet;
4210
4211            // the per-user SELinux context must be set
4212            if (TextUtils.isEmpty(app.info.seInfoUser)) {
4213                Slog.wtf(TAG, "SELinux tag not defined",
4214                        new IllegalStateException("SELinux tag not defined for "
4215                        + app.info.packageName + " (uid " + app.uid + ")"));
4216            }
4217            final String seInfo = app.info.seInfo
4218                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
4219            // Start the process.  It will either succeed and return a result containing
4220            // the PID of the new process, or else throw a RuntimeException.
4221            final String entryPoint = "android.app.ActivityThread";
4222
4223            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
4224                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
4225                    startTime);
4226        } catch (RuntimeException e) {
4227            Slog.e(TAG, "Failure starting process " + app.processName, e);
4228
4229            // Something went very wrong while trying to start this process; one
4230            // common case is when the package is frozen due to an active
4231            // upgrade. To recover, clean up any active bookkeeping related to
4232            // starting this process. (We already invoked this method once when
4233            // the package was initially frozen through KILL_APPLICATION_MSG, so
4234            // it doesn't hurt to use it again.)
4235            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4236                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4237            return false;
4238        }
4239    }
4240
4241    @GuardedBy("this")
4242    private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
4243            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4244            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4245            long startTime) {
4246        app.pendingStart = true;
4247        app.killedByAm = false;
4248        app.removed = false;
4249        app.killed = false;
4250        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
4251        app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
4252        if (mConstants.FLAG_PROCESS_START_ASYNC) {
4253            if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
4254                    "Posting procStart msg for " + app.toShortString());
4255            mProcStartHandler.post(() -> {
4256                try {
4257                    synchronized (ActivityManagerService.this) {
4258                        final String reason = isProcStartValidLocked(app, startSeq);
4259                        if (reason != null) {
4260                            Slog.w(TAG_PROCESSES, app + " not valid anymore,"
4261                                    + " don't start process, " + reason);
4262                            app.pendingStart = false;
4263                            return;
4264                        }
4265                        app.usingWrapper = invokeWith != null
4266                                || SystemProperties.get("wrap." + app.processName) != null;
4267                        mPendingStarts.put(startSeq, app);
4268                    }
4269                    final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
4270                            app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
4271                            requiredAbi, instructionSet, invokeWith, app.startTime);
4272                    synchronized (ActivityManagerService.this) {
4273                        handleProcessStartedLocked(app, startResult, startSeq);
4274                    }
4275                } catch (RuntimeException e) {
4276                    synchronized (ActivityManagerService.this) {
4277                        Slog.e(TAG, "Failure starting process " + app.processName, e);
4278                        mPendingStarts.remove(startSeq);
4279                        app.pendingStart = false;
4280                        forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4281                                false, false, true, false, false,
4282                                UserHandle.getUserId(app.userId), "start failure");
4283                    }
4284                }
4285            });
4286            return true;
4287        } else {
4288            try {
4289                final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
4290                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
4291                        invokeWith, startTime);
4292                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
4293                        startSeq, false);
4294            } catch (RuntimeException e) {
4295                Slog.e(TAG, "Failure starting process " + app.processName, e);
4296                app.pendingStart = false;
4297                forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4298                        false, false, true, false, false,
4299                        UserHandle.getUserId(app.userId), "start failure");
4300            }
4301            return app.pid > 0;
4302        }
4303    }
4304
4305    private ProcessStartResult startProcess(String hostingType, String entryPoint,
4306            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4307            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4308            long startTime) {
4309        try {
4310            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
4311                    app.processName);
4312            checkTime(startTime, "startProcess: asking zygote to start proc");
4313            final ProcessStartResult startResult;
4314            if (hostingType.equals("webview_service")) {
4315                startResult = startWebView(entryPoint,
4316                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4317                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4318                        app.info.dataDir, null,
4319                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4320            } else {
4321                startResult = Process.start(entryPoint,
4322                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4323                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4324                        app.info.dataDir, invokeWith,
4325                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4326            }
4327            checkTime(startTime, "startProcess: returned from zygote!");
4328            return startResult;
4329        } finally {
4330            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4331        }
4332    }
4333
4334    @GuardedBy("this")
4335    private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
4336        StringBuilder sb = null;
4337        if (app.killedByAm) {
4338            if (sb == null) sb = new StringBuilder();
4339            sb.append("killedByAm=true;");
4340        }
4341        if (mProcessNames.get(app.processName, app.uid) != app) {
4342            if (sb == null) sb = new StringBuilder();
4343            sb.append("No entry in mProcessNames;");
4344        }
4345        if (!app.pendingStart) {
4346            if (sb == null) sb = new StringBuilder();
4347            sb.append("pendingStart=false;");
4348        }
4349        if (app.startSeq > expectedStartSeq) {
4350            if (sb == null) sb = new StringBuilder();
4351            sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
4352        }
4353        return sb == null ? null : sb.toString();
4354    }
4355
4356    @GuardedBy("this")
4357    private boolean handleProcessStartedLocked(ProcessRecord pending,
4358            ProcessStartResult startResult, long expectedStartSeq) {
4359        // Indicates that this process start has been taken care of.
4360        if (mPendingStarts.get(expectedStartSeq) == null) {
4361            if (pending.pid == startResult.pid) {
4362                pending.usingWrapper = startResult.usingWrapper;
4363                // TODO: Update already existing clients of usingWrapper
4364            }
4365            return false;
4366        }
4367        return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
4368                expectedStartSeq, false);
4369    }
4370
4371    @GuardedBy("this")
4372    private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
4373            long expectedStartSeq, boolean procAttached) {
4374        mPendingStarts.remove(expectedStartSeq);
4375        final String reason = isProcStartValidLocked(app, expectedStartSeq);
4376        if (reason != null) {
4377            Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
4378                    + ", " + reason);
4379            app.pendingStart = false;
4380            Process.killProcessQuiet(pid);
4381            Process.killProcessGroup(app.uid, app.pid);
4382            return false;
4383        }
4384        mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
4385        checkTime(app.startTime, "startProcess: done updating battery stats");
4386
4387        EventLog.writeEvent(EventLogTags.AM_PROC_START,
4388                UserHandle.getUserId(app.startUid), pid, app.startUid,
4389                app.processName, app.hostingType,
4390                app.hostingNameStr != null ? app.hostingNameStr : "");
4391
4392        try {
4393            AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
4394                    app.seInfo, app.info.sourceDir, pid);
4395        } catch (RemoteException ex) {
4396            // Ignore
4397        }
4398
4399        if (app.persistent) {
4400            Watchdog.getInstance().processStarted(app.processName, pid);
4401        }
4402
4403        checkTime(app.startTime, "startProcess: building log message");
4404        StringBuilder buf = mStringBuilder;
4405        buf.setLength(0);
4406        buf.append("Start proc ");
4407        buf.append(pid);
4408        buf.append(':');
4409        buf.append(app.processName);
4410        buf.append('/');
4411        UserHandle.formatUid(buf, app.startUid);
4412        if (app.isolatedEntryPoint != null) {
4413            buf.append(" [");
4414            buf.append(app.isolatedEntryPoint);
4415            buf.append("]");
4416        }
4417        buf.append(" for ");
4418        buf.append(app.hostingType);
4419        if (app.hostingNameStr != null) {
4420            buf.append(" ");
4421            buf.append(app.hostingNameStr);
4422        }
4423        Slog.i(TAG, buf.toString());
4424        app.setPid(pid);
4425        app.usingWrapper = usingWrapper;
4426        app.pendingStart = false;
4427        checkTime(app.startTime, "startProcess: starting to update pids map");
4428        ProcessRecord oldApp;
4429        synchronized (mPidsSelfLocked) {
4430            oldApp = mPidsSelfLocked.get(pid);
4431        }
4432        // If there is already an app occupying that pid that hasn't been cleaned up
4433        if (oldApp != null && !app.isolated) {
4434            // Clean up anything relating to this pid first
4435            Slog.w(TAG, "Reusing pid " + pid
4436                    + " while app is still mapped to it");
4437            cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4438                    true /*replacingPid*/);
4439        }
4440        synchronized (mPidsSelfLocked) {
4441            this.mPidsSelfLocked.put(pid, app);
4442            if (!procAttached) {
4443                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4444                msg.obj = app;
4445                mHandler.sendMessageDelayed(msg, usingWrapper
4446                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4447            }
4448        }
4449        checkTime(app.startTime, "startProcess: done updating pids map");
4450        return true;
4451    }
4452
4453    void updateUsageStats(ActivityRecord component, boolean resumed) {
4454        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4455                "updateUsageStats: comp=" + component + "res=" + resumed);
4456        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4457        StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
4458            component.app.uid, component.realActivity.getPackageName(),
4459            component.realActivity.getShortClassName(), resumed ?
4460                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__ACTIVITY__MOVE_TO_FOREGROUND :
4461                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__ACTIVITY__MOVE_TO_BACKGROUND);
4462        if (resumed) {
4463            if (mUsageStatsService != null) {
4464                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4465                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4466
4467            }
4468            synchronized (stats) {
4469                stats.noteActivityResumedLocked(component.app.uid);
4470            }
4471        } else {
4472            if (mUsageStatsService != null) {
4473                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4474                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4475            }
4476            synchronized (stats) {
4477                stats.noteActivityPausedLocked(component.app.uid);
4478            }
4479        }
4480    }
4481
4482    Intent getHomeIntent() {
4483        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4484        intent.setComponent(mTopComponent);
4485        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4486        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4487            intent.addCategory(Intent.CATEGORY_HOME);
4488        }
4489        return intent;
4490    }
4491
4492    boolean startHomeActivityLocked(int userId, String reason) {
4493        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4494                && mTopAction == null) {
4495            // We are running in factory test mode, but unable to find
4496            // the factory test app, so just sit around displaying the
4497            // error message and don't try to start anything.
4498            return false;
4499        }
4500        Intent intent = getHomeIntent();
4501        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4502        if (aInfo != null) {
4503            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4504            // Don't do this if the home app is currently being
4505            // instrumented.
4506            aInfo = new ActivityInfo(aInfo);
4507            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4508            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4509                    aInfo.applicationInfo.uid, true);
4510            if (app == null || app.instr == null) {
4511                intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
4512                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4513                // For ANR debugging to verify if the user activity is the one that actually
4514                // launched.
4515                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4516                mActivityStartController.startHomeActivity(intent, aInfo, myReason);
4517            }
4518        } else {
4519            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4520        }
4521
4522        return true;
4523    }
4524
4525    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4526        ActivityInfo ai = null;
4527        ComponentName comp = intent.getComponent();
4528        try {
4529            if (comp != null) {
4530                // Factory test.
4531                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4532            } else {
4533                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4534                        intent,
4535                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4536                        flags, userId);
4537
4538                if (info != null) {
4539                    ai = info.activityInfo;
4540                }
4541            }
4542        } catch (RemoteException e) {
4543            // ignore
4544        }
4545
4546        return ai;
4547    }
4548
4549    boolean getCheckedForSetup() {
4550        return mCheckedForSetup;
4551    }
4552
4553    void setCheckedForSetup(boolean checked) {
4554        mCheckedForSetup = checked;
4555    }
4556
4557    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4558        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4559    }
4560
4561    void enforceNotIsolatedCaller(String caller) {
4562        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4563            throw new SecurityException("Isolated process not allowed to call " + caller);
4564        }
4565    }
4566
4567    @Override
4568    public int getFrontActivityScreenCompatMode() {
4569        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4570        synchronized (this) {
4571            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4572        }
4573    }
4574
4575    @Override
4576    public void setFrontActivityScreenCompatMode(int mode) {
4577        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4578                "setFrontActivityScreenCompatMode");
4579        synchronized (this) {
4580            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4581        }
4582    }
4583
4584    @Override
4585    public int getPackageScreenCompatMode(String packageName) {
4586        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4587        synchronized (this) {
4588            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4589        }
4590    }
4591
4592    @Override
4593    public void setPackageScreenCompatMode(String packageName, int mode) {
4594        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4595                "setPackageScreenCompatMode");
4596        synchronized (this) {
4597            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4598        }
4599    }
4600
4601    @Override
4602    public boolean getPackageAskScreenCompat(String packageName) {
4603        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4604        synchronized (this) {
4605            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4606        }
4607    }
4608
4609    @Override
4610    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4611        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4612                "setPackageAskScreenCompat");
4613        synchronized (this) {
4614            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4615        }
4616    }
4617
4618    private boolean hasUsageStatsPermission(String callingPackage) {
4619        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4620                Binder.getCallingUid(), callingPackage);
4621        if (mode == AppOpsManager.MODE_DEFAULT) {
4622            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4623                    == PackageManager.PERMISSION_GRANTED;
4624        }
4625        return mode == AppOpsManager.MODE_ALLOWED;
4626    }
4627
4628    @Override
4629    public int getPackageProcessState(String packageName, String callingPackage) {
4630        if (!hasUsageStatsPermission(callingPackage)) {
4631            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4632                    "getPackageProcessState");
4633        }
4634
4635        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4636        synchronized (this) {
4637            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4638                final ProcessRecord proc = mLruProcesses.get(i);
4639                if (procState > proc.setProcState) {
4640                    if (proc.pkgList.containsKey(packageName) ||
4641                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4642                        procState = proc.setProcState;
4643                    }
4644                }
4645            }
4646        }
4647        return procState;
4648    }
4649
4650    @Override
4651    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4652            throws RemoteException {
4653        synchronized (this) {
4654            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4655            if (app == null) {
4656                throw new IllegalArgumentException("Unknown process: " + process);
4657            }
4658            if (app.thread == null) {
4659                throw new IllegalArgumentException("Process has no app thread");
4660            }
4661            if (app.trimMemoryLevel >= level) {
4662                throw new IllegalArgumentException(
4663                        "Unable to set a higher trim level than current level");
4664            }
4665            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4666                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4667                throw new IllegalArgumentException("Unable to set a background trim level "
4668                    + "on a foreground process");
4669            }
4670            app.thread.scheduleTrimMemory(level);
4671            app.trimMemoryLevel = level;
4672            return true;
4673        }
4674    }
4675
4676    private void dispatchProcessesChanged() {
4677        int N;
4678        synchronized (this) {
4679            N = mPendingProcessChanges.size();
4680            if (mActiveProcessChanges.length < N) {
4681                mActiveProcessChanges = new ProcessChangeItem[N];
4682            }
4683            mPendingProcessChanges.toArray(mActiveProcessChanges);
4684            mPendingProcessChanges.clear();
4685            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4686                    "*** Delivering " + N + " process changes");
4687        }
4688
4689        int i = mProcessObservers.beginBroadcast();
4690        while (i > 0) {
4691            i--;
4692            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4693            if (observer != null) {
4694                try {
4695                    for (int j=0; j<N; j++) {
4696                        ProcessChangeItem item = mActiveProcessChanges[j];
4697                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4698                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4699                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4700                                    + item.uid + ": " + item.foregroundActivities);
4701                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4702                                    item.foregroundActivities);
4703                        }
4704                    }
4705                } catch (RemoteException e) {
4706                }
4707            }
4708        }
4709        mProcessObservers.finishBroadcast();
4710
4711        synchronized (this) {
4712            for (int j=0; j<N; j++) {
4713                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4714            }
4715        }
4716    }
4717
4718    private void dispatchProcessDied(int pid, int uid) {
4719        int i = mProcessObservers.beginBroadcast();
4720        while (i > 0) {
4721            i--;
4722            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4723            if (observer != null) {
4724                try {
4725                    observer.onProcessDied(pid, uid);
4726                } catch (RemoteException e) {
4727                }
4728            }
4729        }
4730        mProcessObservers.finishBroadcast();
4731    }
4732
4733    @VisibleForTesting
4734    void dispatchUidsChanged() {
4735        int N;
4736        synchronized (this) {
4737            N = mPendingUidChanges.size();
4738            if (mActiveUidChanges.length < N) {
4739                mActiveUidChanges = new UidRecord.ChangeItem[N];
4740            }
4741            for (int i=0; i<N; i++) {
4742                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4743                mActiveUidChanges[i] = change;
4744                if (change.uidRecord != null) {
4745                    change.uidRecord.pendingChange = null;
4746                    change.uidRecord = null;
4747                }
4748            }
4749            mPendingUidChanges.clear();
4750            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4751                    "*** Delivering " + N + " uid changes");
4752        }
4753
4754        mUidChangeDispatchCount += N;
4755        int i = mUidObservers.beginBroadcast();
4756        while (i > 0) {
4757            i--;
4758            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4759                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4760        }
4761        mUidObservers.finishBroadcast();
4762
4763        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4764            for (int j = 0; j < N; ++j) {
4765                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4766                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4767                    mValidateUids.remove(item.uid);
4768                } else {
4769                    UidRecord validateUid = mValidateUids.get(item.uid);
4770                    if (validateUid == null) {
4771                        validateUid = new UidRecord(item.uid);
4772                        mValidateUids.put(item.uid, validateUid);
4773                    }
4774                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4775                        validateUid.idle = true;
4776                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4777                        validateUid.idle = false;
4778                    }
4779                    validateUid.curProcState = validateUid.setProcState = item.processState;
4780                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4781                }
4782            }
4783        }
4784
4785        synchronized (this) {
4786            for (int j = 0; j < N; j++) {
4787                mAvailUidChanges.add(mActiveUidChanges[j]);
4788            }
4789        }
4790    }
4791
4792    private void dispatchUidsChangedForObserver(IUidObserver observer,
4793            UidObserverRegistration reg, int changesSize) {
4794        if (observer == null) {
4795            return;
4796        }
4797        try {
4798            for (int j = 0; j < changesSize; j++) {
4799                UidRecord.ChangeItem item = mActiveUidChanges[j];
4800                final int change = item.change;
4801                if (change == UidRecord.CHANGE_PROCSTATE &&
4802                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4803                    // No-op common case: no significant change, the observer is not
4804                    // interested in all proc state changes.
4805                    continue;
4806                }
4807                final long start = SystemClock.uptimeMillis();
4808                if ((change & UidRecord.CHANGE_IDLE) != 0) {
4809                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4810                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4811                                "UID idle uid=" + item.uid);
4812                        observer.onUidIdle(item.uid, item.ephemeral);
4813                    }
4814                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4815                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4816                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4817                                "UID active uid=" + item.uid);
4818                        observer.onUidActive(item.uid);
4819                    }
4820                }
4821                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4822                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
4823                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4824                                "UID cached uid=" + item.uid);
4825                        observer.onUidCachedChanged(item.uid, true);
4826                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4827                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4828                                "UID active uid=" + item.uid);
4829                        observer.onUidCachedChanged(item.uid, false);
4830                    }
4831                }
4832                if ((change & UidRecord.CHANGE_GONE) != 0) {
4833                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4834                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4835                                "UID gone uid=" + item.uid);
4836                        observer.onUidGone(item.uid, item.ephemeral);
4837                    }
4838                    if (reg.lastProcStates != null) {
4839                        reg.lastProcStates.delete(item.uid);
4840                    }
4841                } else {
4842                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4843                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4844                                "UID CHANGED uid=" + item.uid
4845                                        + ": " + item.processState);
4846                        boolean doReport = true;
4847                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4848                            final int lastState = reg.lastProcStates.get(item.uid,
4849                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4850                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4851                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4852                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4853                                doReport = lastAboveCut != newAboveCut;
4854                            } else {
4855                                doReport = item.processState
4856                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4857                            }
4858                        }
4859                        if (doReport) {
4860                            if (reg.lastProcStates != null) {
4861                                reg.lastProcStates.put(item.uid, item.processState);
4862                            }
4863                            observer.onUidStateChanged(item.uid, item.processState,
4864                                    item.procStateSeq);
4865                        }
4866                    }
4867                }
4868                final int duration = (int) (SystemClock.uptimeMillis() - start);
4869                if (reg.mMaxDispatchTime < duration) {
4870                    reg.mMaxDispatchTime = duration;
4871                }
4872                if (duration >= SLOW_UID_OBSERVER_THRESHOLD_MS) {
4873                    reg.mSlowDispatchCount++;
4874                }
4875            }
4876        } catch (RemoteException e) {
4877        }
4878    }
4879
4880    void dispatchOomAdjObserver(String msg) {
4881        OomAdjObserver observer;
4882        synchronized (this) {
4883            observer = mCurOomAdjObserver;
4884        }
4885
4886        if (observer != null) {
4887            observer.onOomAdjMessage(msg);
4888        }
4889    }
4890
4891    void setOomAdjObserver(int uid, OomAdjObserver observer) {
4892        synchronized (this) {
4893            mCurOomAdjUid = uid;
4894            mCurOomAdjObserver = observer;
4895        }
4896    }
4897
4898    void clearOomAdjObserver() {
4899        synchronized (this) {
4900            mCurOomAdjUid = -1;
4901            mCurOomAdjObserver = null;
4902        }
4903    }
4904
4905    void reportOomAdjMessageLocked(String tag, String msg) {
4906        Slog.d(tag, msg);
4907        if (mCurOomAdjObserver != null) {
4908            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4909        }
4910    }
4911
4912    @Override
4913    public final int startActivity(IApplicationThread caller, String callingPackage,
4914            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4915            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4916        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4917                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4918                UserHandle.getCallingUserId());
4919    }
4920
4921    @Override
4922    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4923            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4924            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4925        enforceNotIsolatedCaller("startActivity");
4926        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4927                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4928        // TODO: Switch to user app stacks here.
4929        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
4930                .setCaller(caller)
4931                .setCallingPackage(callingPackage)
4932                .setResolvedType(resolvedType)
4933                .setResultTo(resultTo)
4934                .setResultWho(resultWho)
4935                .setRequestCode(requestCode)
4936                .setStartFlags(startFlags)
4937                .setProfilerInfo(profilerInfo)
4938                .setActivityOptions(bOptions)
4939                .setMayWait(userId)
4940                .execute();
4941
4942    }
4943
4944    @Override
4945    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4946            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4947            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4948            int userId) {
4949
4950        // This is very dangerous -- it allows you to perform a start activity (including
4951        // permission grants) as any app that may launch one of your own activities.  So
4952        // we will only allow this to be done from activities that are part of the core framework,
4953        // and then only when they are running as the system.
4954        final ActivityRecord sourceRecord;
4955        final int targetUid;
4956        final String targetPackage;
4957        synchronized (this) {
4958            if (resultTo == null) {
4959                throw new SecurityException("Must be called from an activity");
4960            }
4961            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4962            if (sourceRecord == null) {
4963                throw new SecurityException("Called with bad activity token: " + resultTo);
4964            }
4965            if (!sourceRecord.info.packageName.equals("android")) {
4966                throw new SecurityException(
4967                        "Must be called from an activity that is declared in the android package");
4968            }
4969            if (sourceRecord.app == null) {
4970                throw new SecurityException("Called without a process attached to activity");
4971            }
4972            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4973                // This is still okay, as long as this activity is running under the
4974                // uid of the original calling activity.
4975                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4976                    throw new SecurityException(
4977                            "Calling activity in uid " + sourceRecord.app.uid
4978                                    + " must be system uid or original calling uid "
4979                                    + sourceRecord.launchedFromUid);
4980                }
4981            }
4982            if (ignoreTargetSecurity) {
4983                if (intent.getComponent() == null) {
4984                    throw new SecurityException(
4985                            "Component must be specified with ignoreTargetSecurity");
4986                }
4987                if (intent.getSelector() != null) {
4988                    throw new SecurityException(
4989                            "Selector not allowed with ignoreTargetSecurity");
4990                }
4991            }
4992            targetUid = sourceRecord.launchedFromUid;
4993            targetPackage = sourceRecord.launchedFromPackage;
4994        }
4995
4996        if (userId == UserHandle.USER_NULL) {
4997            userId = UserHandle.getUserId(sourceRecord.app.uid);
4998        }
4999
5000        // TODO: Switch to user app stacks here.
5001        try {
5002            return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
5003                    .setCallingUid(targetUid)
5004                    .setCallingPackage(targetPackage)
5005                    .setResolvedType(resolvedType)
5006                    .setResultTo(resultTo)
5007                    .setResultWho(resultWho)
5008                    .setRequestCode(requestCode)
5009                    .setStartFlags(startFlags)
5010                    .setActivityOptions(bOptions)
5011                    .setMayWait(userId)
5012                    .setIgnoreTargetSecurity(ignoreTargetSecurity)
5013                    .execute();
5014        } catch (SecurityException e) {
5015            // XXX need to figure out how to propagate to original app.
5016            // A SecurityException here is generally actually a fault of the original
5017            // calling activity (such as a fairly granting permissions), so propagate it
5018            // back to them.
5019            /*
5020            StringBuilder msg = new StringBuilder();
5021            msg.append("While launching");
5022            msg.append(intent.toString());
5023            msg.append(": ");
5024            msg.append(e.getMessage());
5025            */
5026            throw e;
5027        }
5028    }
5029
5030    @Override
5031    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
5032            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5033            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
5034        enforceNotIsolatedCaller("startActivityAndWait");
5035        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5036                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
5037        WaitResult res = new WaitResult();
5038        // TODO: Switch to user app stacks here.
5039        mActivityStartController.obtainStarter(intent, "startActivityAndWait")
5040                .setCaller(caller)
5041                .setCallingPackage(callingPackage)
5042                .setResolvedType(resolvedType)
5043                .setResultTo(resultTo)
5044                .setResultWho(resultWho)
5045                .setRequestCode(requestCode)
5046                .setStartFlags(startFlags)
5047                .setActivityOptions(bOptions)
5048                .setMayWait(userId)
5049                .setProfilerInfo(profilerInfo)
5050                .setWaitResult(res)
5051                .execute();
5052        return res;
5053    }
5054
5055    @Override
5056    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
5057            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5058            int startFlags, Configuration config, Bundle bOptions, int userId) {
5059        enforceNotIsolatedCaller("startActivityWithConfig");
5060        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5061                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
5062        // TODO: Switch to user app stacks here.
5063        return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
5064                .setCaller(caller)
5065                .setCallingPackage(callingPackage)
5066                .setResolvedType(resolvedType)
5067                .setResultTo(resultTo)
5068                .setResultWho(resultWho)
5069                .setRequestCode(requestCode)
5070                .setStartFlags(startFlags)
5071                .setGlobalConfiguration(config)
5072                .setActivityOptions(bOptions)
5073                .setMayWait(userId)
5074                .execute();
5075    }
5076
5077    @Override
5078    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
5079            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
5080            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
5081            throws TransactionTooLargeException {
5082        enforceNotIsolatedCaller("startActivityIntentSender");
5083        // Refuse possible leaked file descriptors
5084        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
5085            throw new IllegalArgumentException("File descriptors passed in Intent");
5086        }
5087
5088        if (!(target instanceof PendingIntentRecord)) {
5089            throw new IllegalArgumentException("Bad PendingIntent object");
5090        }
5091
5092        PendingIntentRecord pir = (PendingIntentRecord)target;
5093
5094        synchronized (this) {
5095            // If this is coming from the currently resumed activity, it is
5096            // effectively saying that app switches are allowed at this point.
5097            final ActivityStack stack = getFocusedStack();
5098            if (stack.mResumedActivity != null &&
5099                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
5100                mAppSwitchesAllowedTime = 0;
5101            }
5102        }
5103        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
5104                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
5105        return ret;
5106    }
5107
5108    @Override
5109    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
5110            Intent intent, String resolvedType, IVoiceInteractionSession session,
5111            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
5112            Bundle bOptions, int userId) {
5113        enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
5114        if (session == null || interactor == null) {
5115            throw new NullPointerException("null session or interactor");
5116        }
5117        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5118                ALLOW_FULL_ONLY, "startVoiceActivity", null);
5119        // TODO: Switch to user app stacks here.
5120        return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
5121                .setCallingUid(callingUid)
5122                .setCallingPackage(callingPackage)
5123                .setResolvedType(resolvedType)
5124                .setVoiceSession(session)
5125                .setVoiceInteractor(interactor)
5126                .setStartFlags(startFlags)
5127                .setProfilerInfo(profilerInfo)
5128                .setActivityOptions(bOptions)
5129                .setMayWait(userId)
5130                .execute();
5131    }
5132
5133    @Override
5134    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
5135            Intent intent, String resolvedType, Bundle bOptions, int userId) {
5136        enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
5137        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5138                ALLOW_FULL_ONLY, "startAssistantActivity", null);
5139
5140        return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
5141                .setCallingUid(callingUid)
5142                .setCallingPackage(callingPackage)
5143                .setResolvedType(resolvedType)
5144                .setActivityOptions(bOptions)
5145                .setMayWait(userId)
5146                .execute();
5147    }
5148
5149    @Override
5150    public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
5151                IRecentsAnimationRunner recentsAnimationRunner) {
5152        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
5153        final int callingPid = Binder.getCallingPid();
5154        final long origId = Binder.clearCallingIdentity();
5155        try {
5156            final int recentsUid;
5157            final String recentsPackage;
5158            final List<IBinder> topVisibleActivities;
5159            synchronized (this) {
5160                final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
5161                recentsPackage = recentsComponent.getPackageName();
5162                recentsUid = mRecentTasks.getRecentsComponentUid();
5163                topVisibleActivities = mStackSupervisor.getTopVisibleActivities();
5164
5165                // Start a new recents animation
5166                final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
5167                        mActivityStartController, mWindowManager, mUserController, callingPid);
5168                anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
5169                        recentsUid);
5170            }
5171
5172            // If provided, kick off the request for the assist data in the background. Do not hold
5173            // the AM lock as this will just proxy directly to the assist data receiver provided.
5174            if (assistDataReceiver != null) {
5175                final AppOpsManager appOpsManager = (AppOpsManager)
5176                        mContext.getSystemService(Context.APP_OPS_SERVICE);
5177                final AssistDataReceiverProxy proxy = new AssistDataReceiverProxy(
5178                        assistDataReceiver, recentsPackage);
5179                final AssistDataRequester requester = new AssistDataRequester(mContext, this,
5180                        mWindowManager, appOpsManager, proxy, this, OP_ASSIST_STRUCTURE, OP_NONE);
5181                requester.requestAssistData(topVisibleActivities,
5182                        true /* fetchData */, false /* fetchScreenshots */,
5183                        true /* allowFetchData */, false /* allowFetchScreenshots */,
5184                        recentsUid, recentsPackage);
5185            }
5186        } finally {
5187            Binder.restoreCallingIdentity(origId);
5188        }
5189    }
5190
5191    @Override
5192    public void cancelRecentsAnimation() {
5193        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
5194        final long origId = Binder.clearCallingIdentity();
5195        try {
5196            synchronized (this) {
5197                mWindowManager.cancelRecentsAnimation();
5198            }
5199        } finally {
5200            Binder.restoreCallingIdentity(origId);
5201        }
5202    }
5203
5204    @Override
5205    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
5206            throws RemoteException {
5207        Slog.i(TAG, "Activity tried to startVoiceInteraction");
5208        synchronized (this) {
5209            ActivityRecord activity = getFocusedStack().getTopActivity();
5210            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
5211                throw new SecurityException("Only focused activity can call startVoiceInteraction");
5212            }
5213            if (mRunningVoice != null || activity.getTask().voiceSession != null
5214                    || activity.voiceSession != null) {
5215                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
5216                return;
5217            }
5218            if (activity.pendingVoiceInteractionStart) {
5219                Slog.w(TAG, "Pending start of voice interaction already.");
5220                return;
5221            }
5222            activity.pendingVoiceInteractionStart = true;
5223        }
5224        LocalServices.getService(VoiceInteractionManagerInternal.class)
5225                .startLocalVoiceInteraction(callingActivity, options);
5226    }
5227
5228    @Override
5229    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
5230        LocalServices.getService(VoiceInteractionManagerInternal.class)
5231                .stopLocalVoiceInteraction(callingActivity);
5232    }
5233
5234    @Override
5235    public boolean supportsLocalVoiceInteraction() throws RemoteException {
5236        return LocalServices.getService(VoiceInteractionManagerInternal.class)
5237                .supportsLocalVoiceInteraction();
5238    }
5239
5240    @GuardedBy("this")
5241    void onLocalVoiceInteractionStartedLocked(IBinder activity,
5242            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5243        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
5244        if (activityToCallback == null) return;
5245        activityToCallback.setVoiceSessionLocked(voiceSession);
5246
5247        // Inform the activity
5248        try {
5249            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
5250                    voiceInteractor);
5251            long token = Binder.clearCallingIdentity();
5252            try {
5253                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
5254            } finally {
5255                Binder.restoreCallingIdentity(token);
5256            }
5257            // TODO: VI Should we cache the activity so that it's easier to find later
5258            // rather than scan through all the stacks and activities?
5259        } catch (RemoteException re) {
5260            activityToCallback.clearVoiceSessionLocked();
5261            // TODO: VI Should this terminate the voice session?
5262        }
5263    }
5264
5265    @Override
5266    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
5267        synchronized (this) {
5268            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
5269                if (keepAwake) {
5270                    mVoiceWakeLock.acquire();
5271                } else {
5272                    mVoiceWakeLock.release();
5273                }
5274            }
5275        }
5276    }
5277
5278    @Override
5279    public boolean startNextMatchingActivity(IBinder callingActivity,
5280            Intent intent, Bundle bOptions) {
5281        // Refuse possible leaked file descriptors
5282        if (intent != null && intent.hasFileDescriptors() == true) {
5283            throw new IllegalArgumentException("File descriptors passed in Intent");
5284        }
5285        SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
5286
5287        synchronized (this) {
5288            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
5289            if (r == null) {
5290                SafeActivityOptions.abort(options);
5291                return false;
5292            }
5293            if (r.app == null || r.app.thread == null) {
5294                // The caller is not running...  d'oh!
5295                SafeActivityOptions.abort(options);
5296                return false;
5297            }
5298            intent = new Intent(intent);
5299            // The caller is not allowed to change the data.
5300            intent.setDataAndType(r.intent.getData(), r.intent.getType());
5301            // And we are resetting to find the next component...
5302            intent.setComponent(null);
5303
5304            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5305
5306            ActivityInfo aInfo = null;
5307            try {
5308                List<ResolveInfo> resolves =
5309                    AppGlobals.getPackageManager().queryIntentActivities(
5310                            intent, r.resolvedType,
5311                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
5312                            UserHandle.getCallingUserId()).getList();
5313
5314                // Look for the original activity in the list...
5315                final int N = resolves != null ? resolves.size() : 0;
5316                for (int i=0; i<N; i++) {
5317                    ResolveInfo rInfo = resolves.get(i);
5318                    if (rInfo.activityInfo.packageName.equals(r.packageName)
5319                            && rInfo.activityInfo.name.equals(r.info.name)) {
5320                        // We found the current one...  the next matching is
5321                        // after it.
5322                        i++;
5323                        if (i<N) {
5324                            aInfo = resolves.get(i).activityInfo;
5325                        }
5326                        if (debug) {
5327                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
5328                                    + "/" + r.info.name);
5329                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
5330                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
5331                        }
5332                        break;
5333                    }
5334                }
5335            } catch (RemoteException e) {
5336            }
5337
5338            if (aInfo == null) {
5339                // Nobody who is next!
5340                SafeActivityOptions.abort(options);
5341                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
5342                return false;
5343            }
5344
5345            intent.setComponent(new ComponentName(
5346                    aInfo.applicationInfo.packageName, aInfo.name));
5347            intent.setFlags(intent.getFlags()&~(
5348                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
5349                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
5350                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
5351                    FLAG_ACTIVITY_NEW_TASK));
5352
5353            // Okay now we need to start the new activity, replacing the
5354            // currently running activity.  This is a little tricky because
5355            // we want to start the new one as if the current one is finished,
5356            // but not finish the current one first so that there is no flicker.
5357            // And thus...
5358            final boolean wasFinishing = r.finishing;
5359            r.finishing = true;
5360
5361            // Propagate reply information over to the new activity.
5362            final ActivityRecord resultTo = r.resultTo;
5363            final String resultWho = r.resultWho;
5364            final int requestCode = r.requestCode;
5365            r.resultTo = null;
5366            if (resultTo != null) {
5367                resultTo.removeResultsLocked(r, resultWho, requestCode);
5368            }
5369
5370            final long origId = Binder.clearCallingIdentity();
5371            // TODO(b/64750076): Check if calling pid should really be -1.
5372            final int res = mActivityStartController
5373                    .obtainStarter(intent, "startNextMatchingActivity")
5374                    .setCaller(r.app.thread)
5375                    .setResolvedType(r.resolvedType)
5376                    .setActivityInfo(aInfo)
5377                    .setResultTo(resultTo != null ? resultTo.appToken : null)
5378                    .setResultWho(resultWho)
5379                    .setRequestCode(requestCode)
5380                    .setCallingPid(-1)
5381                    .setCallingUid(r.launchedFromUid)
5382                    .setCallingPackage(r.launchedFromPackage)
5383                    .setRealCallingPid(-1)
5384                    .setRealCallingUid(r.launchedFromUid)
5385                    .setActivityOptions(options)
5386                    .execute();
5387            Binder.restoreCallingIdentity(origId);
5388
5389            r.finishing = wasFinishing;
5390            if (res != ActivityManager.START_SUCCESS) {
5391                return false;
5392            }
5393            return true;
5394        }
5395    }
5396
5397    @Override
5398    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
5399        enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
5400                "startActivityFromRecents()");
5401
5402        final int callingPid = Binder.getCallingPid();
5403        final int callingUid = Binder.getCallingUid();
5404        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
5405        final long origId = Binder.clearCallingIdentity();
5406        try {
5407            synchronized (this) {
5408                return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
5409                        safeOptions);
5410            }
5411        } finally {
5412            Binder.restoreCallingIdentity(origId);
5413        }
5414    }
5415
5416    @Override
5417    public final int startActivities(IApplicationThread caller, String callingPackage,
5418            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
5419            int userId) {
5420        final String reason = "startActivities";
5421        enforceNotIsolatedCaller(reason);
5422        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5423                userId, false, ALLOW_FULL_ONLY, reason, null);
5424        // TODO: Switch to user app stacks here.
5425        int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
5426                intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
5427                reason);
5428        return ret;
5429    }
5430
5431    @Override
5432    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
5433        synchronized (this) {
5434            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5435            if (r == null) {
5436                return;
5437            }
5438            r.reportFullyDrawnLocked(restoredFromBundle);
5439        }
5440    }
5441
5442    @Override
5443    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
5444        synchronized (this) {
5445            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5446            if (r == null) {
5447                return;
5448            }
5449            final long origId = Binder.clearCallingIdentity();
5450            try {
5451                r.setRequestedOrientation(requestedOrientation);
5452            } finally {
5453                Binder.restoreCallingIdentity(origId);
5454            }
5455        }
5456    }
5457
5458    @Override
5459    public int getRequestedOrientation(IBinder token) {
5460        synchronized (this) {
5461            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5462            if (r == null) {
5463                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5464            }
5465            return r.getRequestedOrientation();
5466        }
5467    }
5468
5469    /**
5470     * This is the internal entry point for handling Activity.finish().
5471     *
5472     * @param token The Binder token referencing the Activity we want to finish.
5473     * @param resultCode Result code, if any, from this Activity.
5474     * @param resultData Result data (Intent), if any, from this Activity.
5475     * @param finishTask Whether to finish the task associated with this Activity.
5476     *
5477     * @return Returns true if the activity successfully finished, or false if it is still running.
5478     */
5479    @Override
5480    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5481            int finishTask) {
5482        // Refuse possible leaked file descriptors
5483        if (resultData != null && resultData.hasFileDescriptors() == true) {
5484            throw new IllegalArgumentException("File descriptors passed in Intent");
5485        }
5486
5487        synchronized(this) {
5488            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5489            if (r == null) {
5490                return true;
5491            }
5492            // Keep track of the root activity of the task before we finish it
5493            TaskRecord tr = r.getTask();
5494            ActivityRecord rootR = tr.getRootActivity();
5495            if (rootR == null) {
5496                Slog.w(TAG, "Finishing task with all activities already finished");
5497            }
5498            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5499            // finish.
5500            if (mLockTaskController.activityBlockedFromFinish(r)) {
5501                return false;
5502            }
5503
5504            if (mController != null) {
5505                // Find the first activity that is not finishing.
5506                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5507                if (next != null) {
5508                    // ask watcher if this is allowed
5509                    boolean resumeOK = true;
5510                    try {
5511                        resumeOK = mController.activityResuming(next.packageName);
5512                    } catch (RemoteException e) {
5513                        mController = null;
5514                        Watchdog.getInstance().setActivityController(null);
5515                    }
5516
5517                    if (!resumeOK) {
5518                        Slog.i(TAG, "Not finishing activity because controller resumed");
5519                        return false;
5520                    }
5521                }
5522            }
5523            final long origId = Binder.clearCallingIdentity();
5524            try {
5525                boolean res;
5526                final boolean finishWithRootActivity =
5527                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5528                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5529                        || (finishWithRootActivity && r == rootR)) {
5530                    // If requested, remove the task that is associated to this activity only if it
5531                    // was the root activity in the task. The result code and data is ignored
5532                    // because we don't support returning them across task boundaries. Also, to
5533                    // keep backwards compatibility we remove the task from recents when finishing
5534                    // task with root activity.
5535                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5536                            finishWithRootActivity, "finish-activity");
5537                    if (!res) {
5538                        Slog.i(TAG, "Removing task failed to finish activity");
5539                    }
5540                } else {
5541                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5542                            resultData, "app-request", true);
5543                    if (!res) {
5544                        Slog.i(TAG, "Failed to finish by app-request");
5545                    }
5546                }
5547                return res;
5548            } finally {
5549                Binder.restoreCallingIdentity(origId);
5550            }
5551        }
5552    }
5553
5554    @Override
5555    public final void finishHeavyWeightApp() {
5556        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5557                != PackageManager.PERMISSION_GRANTED) {
5558            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5559                    + Binder.getCallingPid()
5560                    + ", uid=" + Binder.getCallingUid()
5561                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5562            Slog.w(TAG, msg);
5563            throw new SecurityException(msg);
5564        }
5565
5566        synchronized(this) {
5567            final ProcessRecord proc = mHeavyWeightProcess;
5568            if (proc == null) {
5569                return;
5570            }
5571
5572            ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
5573            for (int i = 0; i < activities.size(); i++) {
5574                ActivityRecord r = activities.get(i);
5575                if (!r.finishing && r.isInStackLocked()) {
5576                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5577                            null, "finish-heavy", true);
5578                }
5579            }
5580
5581            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5582                    proc.userId, 0));
5583            mHeavyWeightProcess = null;
5584        }
5585    }
5586
5587    @Override
5588    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5589            String message) {
5590        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5591                != PackageManager.PERMISSION_GRANTED) {
5592            String msg = "Permission Denial: crashApplication() from pid="
5593                    + Binder.getCallingPid()
5594                    + ", uid=" + Binder.getCallingUid()
5595                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5596            Slog.w(TAG, msg);
5597            throw new SecurityException(msg);
5598        }
5599
5600        synchronized(this) {
5601            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5602        }
5603    }
5604
5605    @Override
5606    public final void finishSubActivity(IBinder token, String resultWho,
5607            int requestCode) {
5608        synchronized(this) {
5609            final long origId = Binder.clearCallingIdentity();
5610            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5611            if (r != null) {
5612                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5613            }
5614            Binder.restoreCallingIdentity(origId);
5615        }
5616    }
5617
5618    @Override
5619    public boolean finishActivityAffinity(IBinder token) {
5620        synchronized(this) {
5621            final long origId = Binder.clearCallingIdentity();
5622            try {
5623                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5624                if (r == null) {
5625                    return false;
5626                }
5627
5628                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5629                // can finish.
5630                final TaskRecord task = r.getTask();
5631                if (mLockTaskController.activityBlockedFromFinish(r)) {
5632                    return false;
5633                }
5634                return task.getStack().finishActivityAffinityLocked(r);
5635            } finally {
5636                Binder.restoreCallingIdentity(origId);
5637            }
5638        }
5639    }
5640
5641    @Override
5642    public void finishVoiceTask(IVoiceInteractionSession session) {
5643        synchronized (this) {
5644            final long origId = Binder.clearCallingIdentity();
5645            try {
5646                // TODO: VI Consider treating local voice interactions and voice tasks
5647                // differently here
5648                mStackSupervisor.finishVoiceTask(session);
5649            } finally {
5650                Binder.restoreCallingIdentity(origId);
5651            }
5652        }
5653
5654    }
5655
5656    @Override
5657    public boolean releaseActivityInstance(IBinder token) {
5658        synchronized(this) {
5659            final long origId = Binder.clearCallingIdentity();
5660            try {
5661                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5662                if (r == null) {
5663                    return false;
5664                }
5665                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5666            } finally {
5667                Binder.restoreCallingIdentity(origId);
5668            }
5669        }
5670    }
5671
5672    @Override
5673    public void releaseSomeActivities(IApplicationThread appInt) {
5674        synchronized(this) {
5675            final long origId = Binder.clearCallingIdentity();
5676            try {
5677                ProcessRecord app = getRecordForAppLocked(appInt);
5678                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5679            } finally {
5680                Binder.restoreCallingIdentity(origId);
5681            }
5682        }
5683    }
5684
5685    @Override
5686    public boolean willActivityBeVisible(IBinder token) {
5687        synchronized(this) {
5688            ActivityStack stack = ActivityRecord.getStackLocked(token);
5689            if (stack != null) {
5690                return stack.willActivityBeVisibleLocked(token);
5691            }
5692            return false;
5693        }
5694    }
5695
5696    @Override
5697    public void overridePendingTransition(IBinder token, String packageName,
5698            int enterAnim, int exitAnim) {
5699        synchronized(this) {
5700            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5701            if (self == null) {
5702                return;
5703            }
5704
5705            final long origId = Binder.clearCallingIdentity();
5706
5707            if (self.isState(ActivityState.RESUMED, ActivityState.PAUSING)) {
5708                mWindowManager.overridePendingAppTransition(packageName,
5709                        enterAnim, exitAnim, null);
5710            }
5711
5712            Binder.restoreCallingIdentity(origId);
5713        }
5714    }
5715
5716    /**
5717     * Main function for removing an existing process from the activity manager
5718     * as a result of that process going away.  Clears out all connections
5719     * to the process.
5720     */
5721    @GuardedBy("this")
5722    private final void handleAppDiedLocked(ProcessRecord app,
5723            boolean restarting, boolean allowRestart) {
5724        int pid = app.pid;
5725        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5726                false /*replacingPid*/);
5727        if (!kept && !restarting) {
5728            removeLruProcessLocked(app);
5729            if (pid > 0) {
5730                ProcessList.remove(pid);
5731            }
5732        }
5733
5734        if (mProfileProc == app) {
5735            clearProfilerLocked();
5736        }
5737
5738        // Remove this application's activities from active lists.
5739        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5740
5741        app.clearRecentTasks();
5742
5743        app.activities.clear();
5744
5745        if (app.instr != null) {
5746            Slog.w(TAG, "Crash of app " + app.processName
5747                  + " running instrumentation " + app.instr.mClass);
5748            Bundle info = new Bundle();
5749            info.putString("shortMsg", "Process crashed.");
5750            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5751        }
5752
5753        mWindowManager.deferSurfaceLayout();
5754        try {
5755            if (!restarting && hasVisibleActivities
5756                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5757                // If there was nothing to resume, and we are not already restarting this process, but
5758                // there is a visible activity that is hosted by the process...  then make sure all
5759                // visible activities are running, taking care of restarting this process.
5760                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5761            }
5762        } finally {
5763            mWindowManager.continueSurfaceLayout();
5764        }
5765    }
5766
5767    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5768        final IBinder threadBinder = thread.asBinder();
5769        // Find the application record.
5770        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5771            final ProcessRecord rec = mLruProcesses.get(i);
5772            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5773                return i;
5774            }
5775        }
5776        return -1;
5777    }
5778
5779    ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
5780        if (thread == null) {
5781            return null;
5782        }
5783
5784        int appIndex = getLRURecordIndexForAppLocked(thread);
5785        if (appIndex >= 0) {
5786            return mLruProcesses.get(appIndex);
5787        }
5788
5789        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5790        // double-check that.
5791        final IBinder threadBinder = thread.asBinder();
5792        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5793        for (int i = pmap.size()-1; i >= 0; i--) {
5794            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5795            for (int j = procs.size()-1; j >= 0; j--) {
5796                final ProcessRecord proc = procs.valueAt(j);
5797                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5798                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5799                            + proc);
5800                    return proc;
5801                }
5802            }
5803        }
5804
5805        return null;
5806    }
5807
5808    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5809        // If there are no longer any background processes running,
5810        // and the app that died was not running instrumentation,
5811        // then tell everyone we are now low on memory.
5812        boolean haveBg = false;
5813        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5814            ProcessRecord rec = mLruProcesses.get(i);
5815            if (rec.thread != null
5816                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5817                haveBg = true;
5818                break;
5819            }
5820        }
5821
5822        if (!haveBg) {
5823            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5824            if (doReport) {
5825                long now = SystemClock.uptimeMillis();
5826                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5827                    doReport = false;
5828                } else {
5829                    mLastMemUsageReportTime = now;
5830                }
5831            }
5832            final ArrayList<ProcessMemInfo> memInfos
5833                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5834            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5835            long now = SystemClock.uptimeMillis();
5836            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5837                ProcessRecord rec = mLruProcesses.get(i);
5838                if (rec == dyingProc || rec.thread == null) {
5839                    continue;
5840                }
5841                if (doReport) {
5842                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5843                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5844                }
5845                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5846                    // The low memory report is overriding any current
5847                    // state for a GC request.  Make sure to do
5848                    // heavy/important/visible/foreground processes first.
5849                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5850                        rec.lastRequestedGc = 0;
5851                    } else {
5852                        rec.lastRequestedGc = rec.lastLowMemory;
5853                    }
5854                    rec.reportLowMemory = true;
5855                    rec.lastLowMemory = now;
5856                    mProcessesToGc.remove(rec);
5857                    addProcessToGcListLocked(rec);
5858                }
5859            }
5860            if (doReport) {
5861                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5862                mHandler.sendMessage(msg);
5863            }
5864            scheduleAppGcsLocked();
5865        }
5866    }
5867
5868    @GuardedBy("this")
5869    final void appDiedLocked(ProcessRecord app) {
5870       appDiedLocked(app, app.pid, app.thread, false);
5871    }
5872
5873    @GuardedBy("this")
5874    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5875            boolean fromBinderDied) {
5876        // First check if this ProcessRecord is actually active for the pid.
5877        synchronized (mPidsSelfLocked) {
5878            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5879            if (curProc != app) {
5880                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5881                return;
5882            }
5883        }
5884
5885        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5886        synchronized (stats) {
5887            stats.noteProcessDiedLocked(app.info.uid, pid);
5888        }
5889
5890        if (!app.killed) {
5891            if (!fromBinderDied) {
5892                killProcessQuiet(pid);
5893            }
5894            killProcessGroup(app.uid, pid);
5895            app.killed = true;
5896        }
5897
5898        // Clean up already done if the process has been re-started.
5899        if (app.pid == pid && app.thread != null &&
5900                app.thread.asBinder() == thread.asBinder()) {
5901            boolean doLowMem = app.instr == null;
5902            boolean doOomAdj = doLowMem;
5903            if (!app.killedByAm) {
5904                Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5905                        + ProcessList.makeOomAdjString(app.setAdj)
5906                        + ProcessList.makeProcStateString(app.setProcState));
5907                mAllowLowerMemLevel = true;
5908            } else {
5909                // Note that we always want to do oom adj to update our state with the
5910                // new number of procs.
5911                mAllowLowerMemLevel = false;
5912                doLowMem = false;
5913            }
5914            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5915                    app.setAdj, app.setProcState);
5916            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5917                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5918            handleAppDiedLocked(app, false, true);
5919
5920            if (doOomAdj) {
5921                updateOomAdjLocked();
5922            }
5923            if (doLowMem) {
5924                doLowMemReportIfNeededLocked(app);
5925            }
5926        } else if (app.pid != pid) {
5927            // A new process has already been started.
5928            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5929                    + ") has died and restarted (pid " + app.pid + ").");
5930            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5931        } else if (DEBUG_PROCESSES) {
5932            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5933                    + thread.asBinder());
5934        }
5935
5936        // On the device which doesn't have Cgroup, log LmkStateChanged which is used as a signal
5937        // for pulling memory stats of other running processes when this process died.
5938        if (!hasMemcg()) {
5939            StatsLog.write(StatsLog.APP_DIED, SystemClock.elapsedRealtime());
5940        }
5941    }
5942
5943    /**
5944     * If a stack trace dump file is configured, dump process stack traces.
5945     * @param clearTraces causes the dump file to be erased prior to the new
5946     *    traces being written, if true; when false, the new traces will be
5947     *    appended to any existing file content.
5948     * @param firstPids of dalvik VM processes to dump stack traces for first
5949     * @param lastPids of dalvik VM processes to dump stack traces for last
5950     * @param nativePids optional list of native pids to dump stack crawls
5951     */
5952    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5953            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5954            ArrayList<Integer> nativePids) {
5955        ArrayList<Integer> extraPids = null;
5956
5957        // Measure CPU usage as soon as we're called in order to get a realistic sampling
5958        // of the top users at the time of the request.
5959        if (processCpuTracker != null) {
5960            processCpuTracker.init();
5961            try {
5962                Thread.sleep(200);
5963            } catch (InterruptedException ignored) {
5964            }
5965
5966            processCpuTracker.update();
5967
5968            // We'll take the stack crawls of just the top apps using CPU.
5969            final int N = processCpuTracker.countWorkingStats();
5970            extraPids = new ArrayList<>();
5971            for (int i = 0; i < N && extraPids.size() < 5; i++) {
5972                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5973                if (lastPids.indexOfKey(stats.pid) >= 0) {
5974                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5975
5976                    extraPids.add(stats.pid);
5977                } else if (DEBUG_ANR) {
5978                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5979                            + stats.pid);
5980                }
5981            }
5982        }
5983
5984        boolean useTombstonedForJavaTraces = false;
5985        File tracesFile;
5986
5987        final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5988        if (tracesDirProp.isEmpty()) {
5989            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5990            // dumping scheme. All traces are written to a global trace file (usually
5991            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5992            // the file if requested.
5993            //
5994            // This mode of operation will be removed in the near future.
5995
5996
5997            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5998            if (globalTracesPath.isEmpty()) {
5999                Slog.w(TAG, "dumpStackTraces: no trace path configured");
6000                return null;
6001            }
6002
6003            tracesFile = new File(globalTracesPath);
6004            try {
6005                if (clearTraces && tracesFile.exists()) {
6006                    tracesFile.delete();
6007                }
6008
6009                tracesFile.createNewFile();
6010                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
6011            } catch (IOException e) {
6012                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
6013                return null;
6014            }
6015        } else {
6016            File tracesDir = new File(tracesDirProp);
6017            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
6018            // Each set of ANR traces is written to a separate file and dumpstate will process
6019            // all such files and add them to a captured bug report if they're recent enough.
6020            maybePruneOldTraces(tracesDir);
6021
6022            // NOTE: We should consider creating the file in native code atomically once we've
6023            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
6024            // can be removed.
6025            tracesFile = createAnrDumpFile(tracesDir);
6026            if (tracesFile == null) {
6027                return null;
6028            }
6029
6030            useTombstonedForJavaTraces = true;
6031        }
6032
6033        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
6034                useTombstonedForJavaTraces);
6035        return tracesFile;
6036    }
6037
6038    @GuardedBy("ActivityManagerService.class")
6039    private static SimpleDateFormat sAnrFileDateFormat;
6040
6041    private static synchronized File createAnrDumpFile(File tracesDir) {
6042        if (sAnrFileDateFormat == null) {
6043            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
6044        }
6045
6046        final String formattedDate = sAnrFileDateFormat.format(new Date());
6047        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
6048
6049        try {
6050            if (anrFile.createNewFile()) {
6051                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
6052                return anrFile;
6053            } else {
6054                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
6055            }
6056        } catch (IOException ioe) {
6057            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
6058        }
6059
6060        return null;
6061    }
6062
6063    /**
6064     * Prune all trace files that are more than a day old.
6065     *
6066     * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
6067     * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
6068     * since it's the system_server that creates trace files for most ANRs.
6069     */
6070    private static void maybePruneOldTraces(File tracesDir) {
6071        final long now = System.currentTimeMillis();
6072        final File[] traceFiles = tracesDir.listFiles();
6073
6074        if (traceFiles != null) {
6075            for (File file : traceFiles) {
6076                if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
6077                    if (!file.delete()) {
6078                        Slog.w(TAG, "Unable to prune stale trace file: " + file);
6079                    }
6080                }
6081            }
6082        }
6083    }
6084
6085    /**
6086     * Legacy code, do not use. Existing users will be deleted.
6087     *
6088     * @deprecated
6089     */
6090    @Deprecated
6091    public static class DumpStackFileObserver extends FileObserver {
6092        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
6093        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
6094
6095        private final String mTracesPath;
6096        private boolean mClosed;
6097
6098        public DumpStackFileObserver(String tracesPath) {
6099            super(tracesPath, FileObserver.CLOSE_WRITE);
6100            mTracesPath = tracesPath;
6101        }
6102
6103        @Override
6104        public synchronized void onEvent(int event, String path) {
6105            mClosed = true;
6106            notify();
6107        }
6108
6109        public long dumpWithTimeout(int pid, long timeout) {
6110            sendSignal(pid, SIGNAL_QUIT);
6111            final long start = SystemClock.elapsedRealtime();
6112
6113            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
6114            synchronized (this) {
6115                try {
6116                    wait(waitTime); // Wait for traces file to be closed.
6117                } catch (InterruptedException e) {
6118                    Slog.wtf(TAG, e);
6119                }
6120            }
6121
6122            // This avoids a corner case of passing a negative time to the native
6123            // trace in case we've already hit the overall timeout.
6124            final long timeWaited = SystemClock.elapsedRealtime() - start;
6125            if (timeWaited >= timeout) {
6126                return timeWaited;
6127            }
6128
6129            if (!mClosed) {
6130                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
6131                       ". Attempting native stack collection.");
6132
6133                final long nativeDumpTimeoutMs = Math.min(
6134                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
6135
6136                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
6137                        (int) (nativeDumpTimeoutMs / 1000));
6138            }
6139
6140            final long end = SystemClock.elapsedRealtime();
6141            mClosed = false;
6142
6143            return (end - start);
6144        }
6145    }
6146
6147    /**
6148     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
6149     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
6150     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
6151     * attempting to obtain native traces in the case of a failure. Returns the total time spent
6152     * capturing traces.
6153     */
6154    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
6155        final long timeStart = SystemClock.elapsedRealtime();
6156        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
6157            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
6158                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
6159        }
6160
6161        return SystemClock.elapsedRealtime() - timeStart;
6162    }
6163
6164    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
6165            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
6166            boolean useTombstonedForJavaTraces) {
6167
6168        // We don't need any sort of inotify based monitoring when we're dumping traces via
6169        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
6170        // control of all writes to the file in question.
6171        final DumpStackFileObserver observer;
6172        if (useTombstonedForJavaTraces) {
6173            observer = null;
6174        } else {
6175            // Use a FileObserver to detect when traces finish writing.
6176            // The order of traces is considered important to maintain for legibility.
6177            observer = new DumpStackFileObserver(tracesFile);
6178        }
6179
6180        // We must complete all stack dumps within 20 seconds.
6181        long remainingTime = 20 * 1000;
6182        try {
6183            if (observer != null) {
6184                observer.startWatching();
6185            }
6186
6187            // First collect all of the stacks of the most important pids.
6188            if (firstPids != null) {
6189                int num = firstPids.size();
6190                for (int i = 0; i < num; i++) {
6191                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
6192                            + firstPids.get(i));
6193                    final long timeTaken;
6194                    if (useTombstonedForJavaTraces) {
6195                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
6196                    } else {
6197                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
6198                    }
6199
6200                    remainingTime -= timeTaken;
6201                    if (remainingTime <= 0) {
6202                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
6203                            "); deadline exceeded.");
6204                        return;
6205                    }
6206
6207                    if (DEBUG_ANR) {
6208                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
6209                    }
6210                }
6211            }
6212
6213            // Next collect the stacks of the native pids
6214            if (nativePids != null) {
6215                for (int pid : nativePids) {
6216                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
6217                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
6218
6219                    final long start = SystemClock.elapsedRealtime();
6220                    Debug.dumpNativeBacktraceToFileTimeout(
6221                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
6222                    final long timeTaken = SystemClock.elapsedRealtime() - start;
6223
6224                    remainingTime -= timeTaken;
6225                    if (remainingTime <= 0) {
6226                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
6227                            "); deadline exceeded.");
6228                        return;
6229                    }
6230
6231                    if (DEBUG_ANR) {
6232                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
6233                    }
6234                }
6235            }
6236
6237            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
6238            if (extraPids != null) {
6239                for (int pid : extraPids) {
6240                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
6241
6242                    final long timeTaken;
6243                    if (useTombstonedForJavaTraces) {
6244                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
6245                    } else {
6246                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
6247                    }
6248
6249                    remainingTime -= timeTaken;
6250                    if (remainingTime <= 0) {
6251                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
6252                                "); deadline exceeded.");
6253                        return;
6254                    }
6255
6256                    if (DEBUG_ANR) {
6257                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
6258                    }
6259                }
6260            }
6261        } finally {
6262            if (observer != null) {
6263                observer.stopWatching();
6264            }
6265        }
6266    }
6267
6268    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
6269        if (true || Build.IS_USER) {
6270            return;
6271        }
6272        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6273        if (tracesPath == null || tracesPath.length() == 0) {
6274            return;
6275        }
6276
6277        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
6278        StrictMode.allowThreadDiskWrites();
6279        try {
6280            final File tracesFile = new File(tracesPath);
6281            final File tracesDir = tracesFile.getParentFile();
6282            final File tracesTmp = new File(tracesDir, "__tmp__");
6283            try {
6284                if (tracesFile.exists()) {
6285                    tracesTmp.delete();
6286                    tracesFile.renameTo(tracesTmp);
6287                }
6288                StringBuilder sb = new StringBuilder();
6289                Time tobj = new Time();
6290                tobj.set(System.currentTimeMillis());
6291                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
6292                sb.append(": ");
6293                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
6294                sb.append(" since ");
6295                sb.append(msg);
6296                FileOutputStream fos = new FileOutputStream(tracesFile);
6297                fos.write(sb.toString().getBytes());
6298                if (app == null) {
6299                    fos.write("\n*** No application process!".getBytes());
6300                }
6301                fos.close();
6302                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
6303            } catch (IOException e) {
6304                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
6305                return;
6306            }
6307
6308            if (app != null && app.pid > 0) {
6309                ArrayList<Integer> firstPids = new ArrayList<Integer>();
6310                firstPids.add(app.pid);
6311                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
6312            }
6313
6314            File lastTracesFile = null;
6315            File curTracesFile = null;
6316            for (int i=9; i>=0; i--) {
6317                String name = String.format(Locale.US, "slow%02d.txt", i);
6318                curTracesFile = new File(tracesDir, name);
6319                if (curTracesFile.exists()) {
6320                    if (lastTracesFile != null) {
6321                        curTracesFile.renameTo(lastTracesFile);
6322                    } else {
6323                        curTracesFile.delete();
6324                    }
6325                }
6326                lastTracesFile = curTracesFile;
6327            }
6328            tracesFile.renameTo(curTracesFile);
6329            if (tracesTmp.exists()) {
6330                tracesTmp.renameTo(tracesFile);
6331            }
6332        } finally {
6333            StrictMode.setThreadPolicy(oldPolicy);
6334        }
6335    }
6336
6337    @GuardedBy("this")
6338    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
6339        if (!mLaunchWarningShown) {
6340            mLaunchWarningShown = true;
6341            mUiHandler.post(new Runnable() {
6342                @Override
6343                public void run() {
6344                    synchronized (ActivityManagerService.this) {
6345                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
6346                        d.show();
6347                        mUiHandler.postDelayed(new Runnable() {
6348                            @Override
6349                            public void run() {
6350                                synchronized (ActivityManagerService.this) {
6351                                    d.dismiss();
6352                                    mLaunchWarningShown = false;
6353                                }
6354                            }
6355                        }, 4000);
6356                    }
6357                }
6358            });
6359        }
6360    }
6361
6362    @Override
6363    public boolean clearApplicationUserData(final String packageName, boolean keepState,
6364            final IPackageDataObserver observer, int userId) {
6365        enforceNotIsolatedCaller("clearApplicationUserData");
6366        int uid = Binder.getCallingUid();
6367        int pid = Binder.getCallingPid();
6368        final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
6369                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
6370
6371        final ApplicationInfo appInfo;
6372        final boolean isInstantApp;
6373
6374        long callingId = Binder.clearCallingIdentity();
6375        try {
6376            IPackageManager pm = AppGlobals.getPackageManager();
6377            synchronized(this) {
6378                // Instant packages are not protected
6379                if (getPackageManagerInternalLocked().isPackageDataProtected(
6380                        resolvedUserId, packageName)) {
6381                    throw new SecurityException(
6382                            "Cannot clear data for a protected package: " + packageName);
6383                }
6384
6385                ApplicationInfo applicationInfo = null;
6386                try {
6387                    applicationInfo = pm.getApplicationInfo(packageName,
6388                            MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
6389                } catch (RemoteException e) {
6390                    /* ignore */
6391                }
6392                appInfo = applicationInfo;
6393
6394                final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
6395
6396                if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
6397                        pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
6398                    throw new SecurityException("PID " + pid + " does not have permission "
6399                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
6400                            + " of package " + packageName);
6401                }
6402
6403                final boolean hasInstantMetadata = getPackageManagerInternalLocked()
6404                        .hasInstantApplicationMetadata(packageName, resolvedUserId);
6405                final boolean isUninstalledAppWithoutInstantMetadata =
6406                        (appInfo == null && !hasInstantMetadata);
6407                isInstantApp = (appInfo != null && appInfo.isInstantApp())
6408                        || hasInstantMetadata;
6409                final boolean canAccessInstantApps = checkComponentPermission(
6410                        permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
6411                        == PackageManager.PERMISSION_GRANTED;
6412
6413                if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
6414                        && !canAccessInstantApps)) {
6415                    Slog.w(TAG, "Invalid packageName: " + packageName);
6416                    if (observer != null) {
6417                        try {
6418                            observer.onRemoveCompleted(packageName, false);
6419                        } catch (RemoteException e) {
6420                            Slog.i(TAG, "Observer no longer exists.");
6421                        }
6422                    }
6423                    return false;
6424                }
6425
6426                if (appInfo != null) {
6427                    forceStopPackageLocked(packageName, appInfo.uid, "clear data");
6428                    mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
6429                }
6430            }
6431
6432            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
6433                @Override
6434                public void onRemoveCompleted(String packageName, boolean succeeded)
6435                        throws RemoteException {
6436                    if (appInfo != null) {
6437                        synchronized (ActivityManagerService.this) {
6438                            finishForceStopPackageLocked(packageName, appInfo.uid);
6439                        }
6440                    }
6441                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
6442                            Uri.fromParts("package", packageName, null));
6443                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6444                    intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6445                    intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6446                    if (isInstantApp) {
6447                        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6448                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6449                                null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6450                                resolvedUserId);
6451                    } else {
6452                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6453                                null, null, null, null, false, false, resolvedUserId);
6454                    }
6455
6456                    if (observer != null) {
6457                        observer.onRemoveCompleted(packageName, succeeded);
6458                    }
6459                }
6460            };
6461
6462            try {
6463                // Clear application user data
6464                pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6465
6466                if (appInfo != null) {
6467                    // Restore already established notification state and permission grants,
6468                    // so it told us to keep those intact -- it's about to emplace app data
6469                    // that is appropriate for those bits of system state.
6470                    if (!keepState) {
6471                        synchronized (this) {
6472                            // Remove all permissions granted from/to this package
6473                            removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true,
6474                                    false);
6475                        }
6476
6477                        // Reset notification state
6478                        INotificationManager inm = NotificationManager.getService();
6479                        inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6480                    }
6481
6482                    // Clear its scheduled jobs
6483                    JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
6484                    js.cancelJobsForUid(appInfo.uid, "clear data");
6485
6486                    // Clear its pending alarms
6487                    AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
6488                    ami.removeAlarmsForUid(appInfo.uid);
6489                }
6490            } catch (RemoteException e) {
6491            }
6492        } finally {
6493            Binder.restoreCallingIdentity(callingId);
6494        }
6495        return true;
6496    }
6497
6498    @Override
6499    public void killBackgroundProcesses(final String packageName, int userId) {
6500        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6501                != PackageManager.PERMISSION_GRANTED &&
6502                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6503                        != PackageManager.PERMISSION_GRANTED) {
6504            String msg = "Permission Denial: killBackgroundProcesses() from pid="
6505                    + Binder.getCallingPid()
6506                    + ", uid=" + Binder.getCallingUid()
6507                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6508            Slog.w(TAG, msg);
6509            throw new SecurityException(msg);
6510        }
6511
6512        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6513                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6514        final int[] userIds = mUserController.expandUserId(userId);
6515
6516        long callingId = Binder.clearCallingIdentity();
6517        try {
6518            IPackageManager pm = AppGlobals.getPackageManager();
6519            for (int targetUserId : userIds) {
6520                int appId = -1;
6521                try {
6522                    appId = UserHandle.getAppId(
6523                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6524                                    targetUserId));
6525                } catch (RemoteException e) {
6526                }
6527                if (appId == -1) {
6528                    Slog.w(TAG, "Invalid packageName: " + packageName);
6529                    return;
6530                }
6531                synchronized (this) {
6532                    killPackageProcessesLocked(packageName, appId, targetUserId,
6533                            ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6534                }
6535            }
6536        } finally {
6537            Binder.restoreCallingIdentity(callingId);
6538        }
6539    }
6540
6541    @Override
6542    public void killAllBackgroundProcesses() {
6543        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6544                != PackageManager.PERMISSION_GRANTED) {
6545            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6546                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6547                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6548            Slog.w(TAG, msg);
6549            throw new SecurityException(msg);
6550        }
6551
6552        final long callingId = Binder.clearCallingIdentity();
6553        try {
6554            synchronized (this) {
6555                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6556                final int NP = mProcessNames.getMap().size();
6557                for (int ip = 0; ip < NP; ip++) {
6558                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6559                    final int NA = apps.size();
6560                    for (int ia = 0; ia < NA; ia++) {
6561                        final ProcessRecord app = apps.valueAt(ia);
6562                        if (app.persistent) {
6563                            // We don't kill persistent processes.
6564                            continue;
6565                        }
6566                        if (app.removed) {
6567                            procs.add(app);
6568                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6569                            app.removed = true;
6570                            procs.add(app);
6571                        }
6572                    }
6573                }
6574
6575                final int N = procs.size();
6576                for (int i = 0; i < N; i++) {
6577                    removeProcessLocked(procs.get(i), false, true, "kill all background");
6578                }
6579
6580                mAllowLowerMemLevel = true;
6581
6582                updateOomAdjLocked();
6583                doLowMemReportIfNeededLocked(null);
6584            }
6585        } finally {
6586            Binder.restoreCallingIdentity(callingId);
6587        }
6588    }
6589
6590    /**
6591     * Kills all background processes, except those matching any of the
6592     * specified properties.
6593     *
6594     * @param minTargetSdk the target SDK version at or above which to preserve
6595     *                     processes, or {@code -1} to ignore the target SDK
6596     * @param maxProcState the process state at or below which to preserve
6597     *                     processes, or {@code -1} to ignore the process state
6598     */
6599    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6600        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6601                != PackageManager.PERMISSION_GRANTED) {
6602            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6603                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6604                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6605            Slog.w(TAG, msg);
6606            throw new SecurityException(msg);
6607        }
6608
6609        final long callingId = Binder.clearCallingIdentity();
6610        try {
6611            synchronized (this) {
6612                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6613                final int NP = mProcessNames.getMap().size();
6614                for (int ip = 0; ip < NP; ip++) {
6615                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6616                    final int NA = apps.size();
6617                    for (int ia = 0; ia < NA; ia++) {
6618                        final ProcessRecord app = apps.valueAt(ia);
6619                        if (app.removed) {
6620                            procs.add(app);
6621                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6622                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6623                            app.removed = true;
6624                            procs.add(app);
6625                        }
6626                    }
6627                }
6628
6629                final int N = procs.size();
6630                for (int i = 0; i < N; i++) {
6631                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6632                }
6633            }
6634        } finally {
6635            Binder.restoreCallingIdentity(callingId);
6636        }
6637    }
6638
6639    @Override
6640    public void forceStopPackage(final String packageName, int userId) {
6641        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6642                != PackageManager.PERMISSION_GRANTED) {
6643            String msg = "Permission Denial: forceStopPackage() from pid="
6644                    + Binder.getCallingPid()
6645                    + ", uid=" + Binder.getCallingUid()
6646                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6647            Slog.w(TAG, msg);
6648            throw new SecurityException(msg);
6649        }
6650        final int callingPid = Binder.getCallingPid();
6651        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6652                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6653        long callingId = Binder.clearCallingIdentity();
6654        try {
6655            IPackageManager pm = AppGlobals.getPackageManager();
6656            synchronized(this) {
6657                int[] users = userId == UserHandle.USER_ALL
6658                        ? mUserController.getUsers() : new int[] { userId };
6659                for (int user : users) {
6660                    int pkgUid = -1;
6661                    try {
6662                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6663                                user);
6664                    } catch (RemoteException e) {
6665                    }
6666                    if (pkgUid == -1) {
6667                        Slog.w(TAG, "Invalid packageName: " + packageName);
6668                        continue;
6669                    }
6670                    try {
6671                        pm.setPackageStoppedState(packageName, true, user);
6672                    } catch (RemoteException e) {
6673                    } catch (IllegalArgumentException e) {
6674                        Slog.w(TAG, "Failed trying to unstop package "
6675                                + packageName + ": " + e);
6676                    }
6677                    if (mUserController.isUserRunning(user, 0)) {
6678                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6679                        finishForceStopPackageLocked(packageName, pkgUid);
6680                    }
6681                }
6682            }
6683        } finally {
6684            Binder.restoreCallingIdentity(callingId);
6685        }
6686    }
6687
6688    @Override
6689    public void addPackageDependency(String packageName) {
6690        synchronized (this) {
6691            int callingPid = Binder.getCallingPid();
6692            if (callingPid == myPid()) {
6693                //  Yeah, um, no.
6694                return;
6695            }
6696            ProcessRecord proc;
6697            synchronized (mPidsSelfLocked) {
6698                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6699            }
6700            if (proc != null) {
6701                if (proc.pkgDeps == null) {
6702                    proc.pkgDeps = new ArraySet<String>(1);
6703                }
6704                proc.pkgDeps.add(packageName);
6705            }
6706        }
6707    }
6708
6709    /*
6710     * The pkg name and app id have to be specified.
6711     */
6712    @Override
6713    public void killApplication(String pkg, int appId, int userId, String reason) {
6714        if (pkg == null) {
6715            return;
6716        }
6717        // Make sure the uid is valid.
6718        if (appId < 0) {
6719            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6720            return;
6721        }
6722        int callerUid = Binder.getCallingUid();
6723        // Only the system server can kill an application
6724        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6725            // Post an aysnc message to kill the application
6726            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6727            msg.arg1 = appId;
6728            msg.arg2 = userId;
6729            Bundle bundle = new Bundle();
6730            bundle.putString("pkg", pkg);
6731            bundle.putString("reason", reason);
6732            msg.obj = bundle;
6733            mHandler.sendMessage(msg);
6734        } else {
6735            throw new SecurityException(callerUid + " cannot kill pkg: " +
6736                    pkg);
6737        }
6738    }
6739
6740    @Override
6741    public void closeSystemDialogs(String reason) {
6742        enforceNotIsolatedCaller("closeSystemDialogs");
6743
6744        final int pid = Binder.getCallingPid();
6745        final int uid = Binder.getCallingUid();
6746        final long origId = Binder.clearCallingIdentity();
6747        try {
6748            synchronized (this) {
6749                // Only allow this from foreground processes, so that background
6750                // applications can't abuse it to prevent system UI from being shown.
6751                if (uid >= FIRST_APPLICATION_UID) {
6752                    ProcessRecord proc;
6753                    synchronized (mPidsSelfLocked) {
6754                        proc = mPidsSelfLocked.get(pid);
6755                    }
6756                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6757                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6758                                + " from background process " + proc);
6759                        return;
6760                    }
6761                }
6762                closeSystemDialogsLocked(reason);
6763            }
6764        } finally {
6765            Binder.restoreCallingIdentity(origId);
6766        }
6767    }
6768
6769    @GuardedBy("this")
6770    void closeSystemDialogsLocked(String reason) {
6771        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6772        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6773                | Intent.FLAG_RECEIVER_FOREGROUND);
6774        if (reason != null) {
6775            intent.putExtra("reason", reason);
6776        }
6777        mWindowManager.closeSystemDialogs(reason);
6778
6779        mStackSupervisor.closeSystemDialogsLocked();
6780
6781        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6782                OP_NONE, null, false, false,
6783                -1, SYSTEM_UID, UserHandle.USER_ALL);
6784    }
6785
6786    @Override
6787    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6788        enforceNotIsolatedCaller("getProcessMemoryInfo");
6789        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6790        for (int i=pids.length-1; i>=0; i--) {
6791            ProcessRecord proc;
6792            int oomAdj;
6793            synchronized (this) {
6794                synchronized (mPidsSelfLocked) {
6795                    proc = mPidsSelfLocked.get(pids[i]);
6796                    oomAdj = proc != null ? proc.setAdj : 0;
6797                }
6798            }
6799            infos[i] = new Debug.MemoryInfo();
6800            long startTime = SystemClock.currentThreadTimeMillis();
6801            Debug.getMemoryInfo(pids[i], infos[i]);
6802            long endTime = SystemClock.currentThreadTimeMillis();
6803            if (proc != null) {
6804                synchronized (this) {
6805                    if (proc.thread != null && proc.setAdj == oomAdj) {
6806                        // Record this for posterity if the process has been stable.
6807                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6808                                infos[i].getTotalUss(), infos[i].getTotalRss(), false,
6809                                ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
6810                                proc.pkgList);
6811                    }
6812                }
6813            }
6814        }
6815        return infos;
6816    }
6817
6818    @Override
6819    public long[] getProcessPss(int[] pids) {
6820        enforceNotIsolatedCaller("getProcessPss");
6821        long[] pss = new long[pids.length];
6822        for (int i=pids.length-1; i>=0; i--) {
6823            ProcessRecord proc;
6824            int oomAdj;
6825            synchronized (this) {
6826                synchronized (mPidsSelfLocked) {
6827                    proc = mPidsSelfLocked.get(pids[i]);
6828                    oomAdj = proc != null ? proc.setAdj : 0;
6829                }
6830            }
6831            long[] tmpUss = new long[3];
6832            long startTime = SystemClock.currentThreadTimeMillis();
6833            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6834            long endTime = SystemClock.currentThreadTimeMillis();
6835            if (proc != null) {
6836                synchronized (this) {
6837                    if (proc.thread != null && proc.setAdj == oomAdj) {
6838                        // Record this for posterity if the process has been stable.
6839                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
6840                                ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
6841                    }
6842                }
6843            }
6844        }
6845        return pss;
6846    }
6847
6848    @Override
6849    public void killApplicationProcess(String processName, int uid) {
6850        if (processName == null) {
6851            return;
6852        }
6853
6854        int callerUid = Binder.getCallingUid();
6855        // Only the system server can kill an application
6856        if (callerUid == SYSTEM_UID) {
6857            synchronized (this) {
6858                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6859                if (app != null && app.thread != null) {
6860                    try {
6861                        app.thread.scheduleSuicide();
6862                    } catch (RemoteException e) {
6863                        // If the other end already died, then our work here is done.
6864                    }
6865                } else {
6866                    Slog.w(TAG, "Process/uid not found attempting kill of "
6867                            + processName + " / " + uid);
6868                }
6869            }
6870        } else {
6871            throw new SecurityException(callerUid + " cannot kill app process: " +
6872                    processName);
6873        }
6874    }
6875
6876    @GuardedBy("this")
6877    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6878        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6879                false, true, false, false, UserHandle.getUserId(uid), reason);
6880    }
6881
6882    @GuardedBy("this")
6883    private void finishForceStopPackageLocked(final String packageName, int uid) {
6884        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6885                Uri.fromParts("package", packageName, null));
6886        if (!mProcessesReady) {
6887            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6888                    | Intent.FLAG_RECEIVER_FOREGROUND);
6889        }
6890        intent.putExtra(Intent.EXTRA_UID, uid);
6891        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6892        broadcastIntentLocked(null, null, intent,
6893                null, null, 0, null, null, null, OP_NONE,
6894                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6895    }
6896
6897
6898    @GuardedBy("this")
6899    private final boolean killPackageProcessesLocked(String packageName, int appId,
6900            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6901            boolean doit, boolean evenPersistent, String reason) {
6902        ArrayList<ProcessRecord> procs = new ArrayList<>();
6903
6904        // Remove all processes this package may have touched: all with the
6905        // same UID (except for the system or root user), and all whose name
6906        // matches the package name.
6907        final int NP = mProcessNames.getMap().size();
6908        for (int ip=0; ip<NP; ip++) {
6909            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6910            final int NA = apps.size();
6911            for (int ia=0; ia<NA; ia++) {
6912                ProcessRecord app = apps.valueAt(ia);
6913                if (app.persistent && !evenPersistent) {
6914                    // we don't kill persistent processes
6915                    continue;
6916                }
6917                if (app.removed) {
6918                    if (doit) {
6919                        procs.add(app);
6920                    }
6921                    continue;
6922                }
6923
6924                // Skip process if it doesn't meet our oom adj requirement.
6925                if (app.setAdj < minOomAdj) {
6926                    continue;
6927                }
6928
6929                // If no package is specified, we call all processes under the
6930                // give user id.
6931                if (packageName == null) {
6932                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6933                        continue;
6934                    }
6935                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6936                        continue;
6937                    }
6938                // Package has been specified, we want to hit all processes
6939                // that match it.  We need to qualify this by the processes
6940                // that are running under the specified app and user ID.
6941                } else {
6942                    final boolean isDep = app.pkgDeps != null
6943                            && app.pkgDeps.contains(packageName);
6944                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6945                        continue;
6946                    }
6947                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6948                        continue;
6949                    }
6950                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6951                        continue;
6952                    }
6953                }
6954
6955                // Process has passed all conditions, kill it!
6956                if (!doit) {
6957                    return true;
6958                }
6959                app.removed = true;
6960                procs.add(app);
6961            }
6962        }
6963
6964        int N = procs.size();
6965        for (int i=0; i<N; i++) {
6966            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6967        }
6968        updateOomAdjLocked();
6969        return N > 0;
6970    }
6971
6972    private void cleanupDisabledPackageComponentsLocked(
6973            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6974
6975        Set<String> disabledClasses = null;
6976        boolean packageDisabled = false;
6977        IPackageManager pm = AppGlobals.getPackageManager();
6978
6979        if (changedClasses == null) {
6980            // Nothing changed...
6981            return;
6982        }
6983
6984        // Determine enable/disable state of the package and its components.
6985        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6986        for (int i = changedClasses.length - 1; i >= 0; i--) {
6987            final String changedClass = changedClasses[i];
6988
6989            if (changedClass.equals(packageName)) {
6990                try {
6991                    // Entire package setting changed
6992                    enabled = pm.getApplicationEnabledSetting(packageName,
6993                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6994                } catch (Exception e) {
6995                    // No such package/component; probably racing with uninstall.  In any
6996                    // event it means we have nothing further to do here.
6997                    return;
6998                }
6999                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
7000                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
7001                if (packageDisabled) {
7002                    // Entire package is disabled.
7003                    // No need to continue to check component states.
7004                    disabledClasses = null;
7005                    break;
7006                }
7007            } else {
7008                try {
7009                    enabled = pm.getComponentEnabledSetting(
7010                            new ComponentName(packageName, changedClass),
7011                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
7012                } catch (Exception e) {
7013                    // As above, probably racing with uninstall.
7014                    return;
7015                }
7016                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
7017                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
7018                    if (disabledClasses == null) {
7019                        disabledClasses = new ArraySet<>(changedClasses.length);
7020                    }
7021                    disabledClasses.add(changedClass);
7022                }
7023            }
7024        }
7025
7026        if (!packageDisabled && disabledClasses == null) {
7027            // Nothing to do here...
7028            return;
7029        }
7030
7031        // Clean-up disabled activities.
7032        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7033                packageName, disabledClasses, true, false, userId) && mBooted) {
7034            mStackSupervisor.resumeFocusedStackTopActivityLocked();
7035            mStackSupervisor.scheduleIdleLocked();
7036        }
7037
7038        // Clean-up disabled tasks
7039        mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
7040
7041        // Clean-up disabled services.
7042        mServices.bringDownDisabledPackageServicesLocked(
7043                packageName, disabledClasses, userId, false, killProcess, true);
7044
7045        // Clean-up disabled providers.
7046        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7047        mProviderMap.collectPackageProvidersLocked(
7048                packageName, disabledClasses, true, false, userId, providers);
7049        for (int i = providers.size() - 1; i >= 0; i--) {
7050            removeDyingProviderLocked(null, providers.get(i), true);
7051        }
7052
7053        // Clean-up disabled broadcast receivers.
7054        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7055            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7056                    packageName, disabledClasses, userId, true);
7057        }
7058
7059    }
7060
7061    final boolean clearBroadcastQueueForUserLocked(int userId) {
7062        boolean didSomething = false;
7063        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7064            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7065                    null, null, userId, true);
7066        }
7067        return didSomething;
7068    }
7069
7070    @GuardedBy("this")
7071    final boolean forceStopPackageLocked(String packageName, int appId,
7072            boolean callerWillRestart, boolean purgeCache, boolean doit,
7073            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
7074        int i;
7075
7076        if (userId == UserHandle.USER_ALL && packageName == null) {
7077            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
7078        }
7079
7080        if (appId < 0 && packageName != null) {
7081            try {
7082                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
7083                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
7084            } catch (RemoteException e) {
7085            }
7086        }
7087
7088        if (doit) {
7089            if (packageName != null) {
7090                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
7091                        + " user=" + userId + ": " + reason);
7092            } else {
7093                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
7094            }
7095
7096            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
7097        }
7098
7099        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
7100                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
7101                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
7102
7103        didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
7104
7105        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7106                packageName, null, doit, evenPersistent, userId)) {
7107            if (!doit) {
7108                return true;
7109            }
7110            didSomething = true;
7111        }
7112
7113        if (mServices.bringDownDisabledPackageServicesLocked(
7114                packageName, null, userId, evenPersistent, true, doit)) {
7115            if (!doit) {
7116                return true;
7117            }
7118            didSomething = true;
7119        }
7120
7121        if (packageName == null) {
7122            // Remove all sticky broadcasts from this user.
7123            mStickyBroadcasts.remove(userId);
7124        }
7125
7126        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7127        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
7128                userId, providers)) {
7129            if (!doit) {
7130                return true;
7131            }
7132            didSomething = true;
7133        }
7134        for (i = providers.size() - 1; i >= 0; i--) {
7135            removeDyingProviderLocked(null, providers.get(i), true);
7136        }
7137
7138        // Remove transient permissions granted from/to this package/user
7139        removeUriPermissionsForPackageLocked(packageName, userId, false, false);
7140
7141        if (doit) {
7142            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
7143                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7144                        packageName, null, userId, doit);
7145            }
7146        }
7147
7148        if (packageName == null || uninstalling) {
7149            // Remove pending intents.  For now we only do this when force
7150            // stopping users, because we have some problems when doing this
7151            // for packages -- app widgets are not currently cleaned up for
7152            // such packages, so they can be left with bad pending intents.
7153            if (mIntentSenderRecords.size() > 0) {
7154                Iterator<WeakReference<PendingIntentRecord>> it
7155                        = mIntentSenderRecords.values().iterator();
7156                while (it.hasNext()) {
7157                    WeakReference<PendingIntentRecord> wpir = it.next();
7158                    if (wpir == null) {
7159                        it.remove();
7160                        continue;
7161                    }
7162                    PendingIntentRecord pir = wpir.get();
7163                    if (pir == null) {
7164                        it.remove();
7165                        continue;
7166                    }
7167                    if (packageName == null) {
7168                        // Stopping user, remove all objects for the user.
7169                        if (pir.key.userId != userId) {
7170                            // Not the same user, skip it.
7171                            continue;
7172                        }
7173                    } else {
7174                        if (UserHandle.getAppId(pir.uid) != appId) {
7175                            // Different app id, skip it.
7176                            continue;
7177                        }
7178                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
7179                            // Different user, skip it.
7180                            continue;
7181                        }
7182                        if (!pir.key.packageName.equals(packageName)) {
7183                            // Different package, skip it.
7184                            continue;
7185                        }
7186                    }
7187                    if (!doit) {
7188                        return true;
7189                    }
7190                    didSomething = true;
7191                    it.remove();
7192                    makeIntentSenderCanceledLocked(pir);
7193                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
7194                        pir.key.activity.pendingResults.remove(pir.ref);
7195                    }
7196                }
7197            }
7198        }
7199
7200        if (doit) {
7201            if (purgeCache && packageName != null) {
7202                AttributeCache ac = AttributeCache.instance();
7203                if (ac != null) {
7204                    ac.removePackage(packageName);
7205                }
7206            }
7207            if (mBooted) {
7208                mStackSupervisor.resumeFocusedStackTopActivityLocked();
7209                mStackSupervisor.scheduleIdleLocked();
7210            }
7211        }
7212
7213        return didSomething;
7214    }
7215
7216    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
7217        return removeProcessNameLocked(name, uid, null);
7218    }
7219
7220    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
7221            final ProcessRecord expecting) {
7222        ProcessRecord old = mProcessNames.get(name, uid);
7223        // Only actually remove when the currently recorded value matches the
7224        // record that we expected; if it doesn't match then we raced with a
7225        // newly created process and we don't want to destroy the new one.
7226        if ((expecting == null) || (old == expecting)) {
7227            mProcessNames.remove(name, uid);
7228        }
7229        if (old != null && old.uidRecord != null) {
7230            old.uidRecord.numProcs--;
7231            if (old.uidRecord.numProcs == 0) {
7232                // No more processes using this uid, tell clients it is gone.
7233                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7234                        "No more processes in " + old.uidRecord);
7235                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
7236                EventLogTags.writeAmUidStopped(uid);
7237                mActiveUids.remove(uid);
7238                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
7239            }
7240            old.uidRecord = null;
7241        }
7242        mIsolatedProcesses.remove(uid);
7243        return old;
7244    }
7245
7246    private final void addProcessNameLocked(ProcessRecord proc) {
7247        // We shouldn't already have a process under this name, but just in case we
7248        // need to clean up whatever may be there now.
7249        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
7250        if (old == proc && proc.persistent) {
7251            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
7252            Slog.w(TAG, "Re-adding persistent process " + proc);
7253        } else if (old != null) {
7254            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
7255        }
7256        UidRecord uidRec = mActiveUids.get(proc.uid);
7257        if (uidRec == null) {
7258            uidRec = new UidRecord(proc.uid);
7259            // This is the first appearance of the uid, report it now!
7260            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7261                    "Creating new process uid: " + uidRec);
7262            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
7263                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
7264                uidRec.setWhitelist = uidRec.curWhitelist = true;
7265            }
7266            uidRec.updateHasInternetPermission();
7267            mActiveUids.put(proc.uid, uidRec);
7268            EventLogTags.writeAmUidRunning(uidRec.uid);
7269            noteUidProcessState(uidRec.uid, uidRec.curProcState);
7270        }
7271        proc.uidRecord = uidRec;
7272
7273        // Reset render thread tid if it was already set, so new process can set it again.
7274        proc.renderThreadTid = 0;
7275        uidRec.numProcs++;
7276        mProcessNames.put(proc.processName, proc.uid, proc);
7277        if (proc.isolated) {
7278            mIsolatedProcesses.put(proc.uid, proc);
7279        }
7280    }
7281
7282    @GuardedBy("this")
7283    boolean removeProcessLocked(ProcessRecord app,
7284            boolean callerWillRestart, boolean allowRestart, String reason) {
7285        final String name = app.processName;
7286        final int uid = app.uid;
7287        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
7288            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
7289
7290        ProcessRecord old = mProcessNames.get(name, uid);
7291        if (old != app) {
7292            // This process is no longer active, so nothing to do.
7293            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
7294            return false;
7295        }
7296        removeProcessNameLocked(name, uid);
7297        if (mHeavyWeightProcess == app) {
7298            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7299                    mHeavyWeightProcess.userId, 0));
7300            mHeavyWeightProcess = null;
7301        }
7302        boolean needRestart = false;
7303        if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
7304            int pid = app.pid;
7305            if (pid > 0) {
7306                synchronized (mPidsSelfLocked) {
7307                    mPidsSelfLocked.remove(pid);
7308                    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7309                }
7310                mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7311                if (app.isolated) {
7312                    mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7313                    getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
7314                }
7315            }
7316            boolean willRestart = false;
7317            if (app.persistent && !app.isolated) {
7318                if (!callerWillRestart) {
7319                    willRestart = true;
7320                } else {
7321                    needRestart = true;
7322                }
7323            }
7324            app.kill(reason, true);
7325            handleAppDiedLocked(app, willRestart, allowRestart);
7326            if (willRestart) {
7327                removeLruProcessLocked(app);
7328                addAppLocked(app.info, null, false, null /* ABI override */);
7329            }
7330        } else {
7331            mRemovedProcesses.add(app);
7332        }
7333
7334        return needRestart;
7335    }
7336
7337    @GuardedBy("this")
7338    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
7339        cleanupAppInLaunchingProvidersLocked(app, true);
7340        removeProcessLocked(app, false, true, "timeout publishing content providers");
7341    }
7342
7343    private final void processStartTimedOutLocked(ProcessRecord app) {
7344        final int pid = app.pid;
7345        boolean gone = false;
7346        synchronized (mPidsSelfLocked) {
7347            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
7348            if (knownApp != null && knownApp.thread == null) {
7349                mPidsSelfLocked.remove(pid);
7350                gone = true;
7351            }
7352        }
7353
7354        if (gone) {
7355            Slog.w(TAG, "Process " + app + " failed to attach");
7356            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
7357                    pid, app.uid, app.processName);
7358            removeProcessNameLocked(app.processName, app.uid);
7359            if (mHeavyWeightProcess == app) {
7360                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7361                        mHeavyWeightProcess.userId, 0));
7362                mHeavyWeightProcess = null;
7363            }
7364            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7365            // Take care of any launching providers waiting for this process.
7366            cleanupAppInLaunchingProvidersLocked(app, true);
7367            // Take care of any services that are waiting for the process.
7368            mServices.processStartTimedOutLocked(app);
7369            app.kill("start timeout", true);
7370            if (app.isolated) {
7371                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7372            }
7373            removeLruProcessLocked(app);
7374            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
7375                Slog.w(TAG, "Unattached app died before backup, skipping");
7376                mHandler.post(new Runnable() {
7377                @Override
7378                    public void run(){
7379                        try {
7380                            IBackupManager bm = IBackupManager.Stub.asInterface(
7381                                    ServiceManager.getService(Context.BACKUP_SERVICE));
7382                            bm.agentDisconnected(app.info.packageName);
7383                        } catch (RemoteException e) {
7384                            // Can't happen; the backup manager is local
7385                        }
7386                    }
7387                });
7388            }
7389            if (isPendingBroadcastProcessLocked(pid)) {
7390                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
7391                skipPendingBroadcastLocked(pid);
7392            }
7393        } else {
7394            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
7395        }
7396    }
7397
7398    @GuardedBy("this")
7399    private final boolean attachApplicationLocked(IApplicationThread thread,
7400            int pid, int callingUid, long startSeq) {
7401
7402        // Find the application record that is being attached...  either via
7403        // the pid if we are running in multiple processes, or just pull the
7404        // next app record if we are emulating process with anonymous threads.
7405        ProcessRecord app;
7406        long startTime = SystemClock.uptimeMillis();
7407        if (pid != MY_PID && pid >= 0) {
7408            synchronized (mPidsSelfLocked) {
7409                app = mPidsSelfLocked.get(pid);
7410            }
7411        } else {
7412            app = null;
7413        }
7414
7415        // It's possible that process called attachApplication before we got a chance to
7416        // update the internal state.
7417        if (app == null && startSeq > 0) {
7418            final ProcessRecord pending = mPendingStarts.get(startSeq);
7419            if (pending != null && pending.startUid == callingUid
7420                    && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
7421                            startSeq, true)) {
7422                app = pending;
7423            }
7424        }
7425
7426        if (app == null) {
7427            Slog.w(TAG, "No pending application record for pid " + pid
7428                    + " (IApplicationThread " + thread + "); dropping process");
7429            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
7430            if (pid > 0 && pid != MY_PID) {
7431                killProcessQuiet(pid);
7432                //TODO: killProcessGroup(app.info.uid, pid);
7433            } else {
7434                try {
7435                    thread.scheduleExit();
7436                } catch (Exception e) {
7437                    // Ignore exceptions.
7438                }
7439            }
7440            return false;
7441        }
7442
7443        // If this application record is still attached to a previous
7444        // process, clean it up now.
7445        if (app.thread != null) {
7446            handleAppDiedLocked(app, true, true);
7447        }
7448
7449        // Tell the process all about itself.
7450
7451        if (DEBUG_ALL) Slog.v(
7452                TAG, "Binding process pid " + pid + " to record " + app);
7453
7454        final String processName = app.processName;
7455        try {
7456            AppDeathRecipient adr = new AppDeathRecipient(
7457                    app, pid, thread);
7458            thread.asBinder().linkToDeath(adr, 0);
7459            app.deathRecipient = adr;
7460        } catch (RemoteException e) {
7461            app.resetPackageList(mProcessStats);
7462            startProcessLocked(app, "link fail", processName);
7463            return false;
7464        }
7465
7466        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
7467
7468        app.makeActive(thread, mProcessStats);
7469        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
7470        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
7471        app.forcingToImportant = null;
7472        updateProcessForegroundLocked(app, false, false);
7473        app.hasShownUi = false;
7474        app.debugging = false;
7475        app.cached = false;
7476        app.killedByAm = false;
7477        app.killed = false;
7478
7479
7480        // We carefully use the same state that PackageManager uses for
7481        // filtering, since we use this flag to decide if we need to install
7482        // providers when user is unlocked later
7483        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
7484
7485        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7486
7487        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
7488        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7489
7490        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7491            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7492            msg.obj = app;
7493            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7494        }
7495
7496        checkTime(startTime, "attachApplicationLocked: before bindApplication");
7497
7498        if (!normalMode) {
7499            Slog.i(TAG, "Launching preboot mode app: " + app);
7500        }
7501
7502        if (DEBUG_ALL) Slog.v(
7503            TAG, "New app record " + app
7504            + " thread=" + thread.asBinder() + " pid=" + pid);
7505        try {
7506            int testMode = ApplicationThreadConstants.DEBUG_OFF;
7507            if (mDebugApp != null && mDebugApp.equals(processName)) {
7508                testMode = mWaitForDebugger
7509                    ? ApplicationThreadConstants.DEBUG_WAIT
7510                    : ApplicationThreadConstants.DEBUG_ON;
7511                app.debugging = true;
7512                if (mDebugTransient) {
7513                    mDebugApp = mOrigDebugApp;
7514                    mWaitForDebugger = mOrigWaitForDebugger;
7515                }
7516            }
7517
7518            boolean enableTrackAllocation = false;
7519            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7520                enableTrackAllocation = true;
7521                mTrackAllocationApp = null;
7522            }
7523
7524            // If the app is being launched for restore or full backup, set it up specially
7525            boolean isRestrictedBackupMode = false;
7526            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7527                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7528                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7529                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7530                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7531            }
7532
7533            if (app.instr != null) {
7534                notifyPackageUse(app.instr.mClass.getPackageName(),
7535                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7536            }
7537            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7538                    + processName + " with config " + getGlobalConfiguration());
7539            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7540            app.compat = compatibilityInfoForPackageLocked(appInfo);
7541
7542            ProfilerInfo profilerInfo = null;
7543            String preBindAgent = null;
7544            if (mProfileApp != null && mProfileApp.equals(processName)) {
7545                mProfileProc = app;
7546                if (mProfilerInfo != null) {
7547                    // Send a profiler info object to the app if either a file is given, or
7548                    // an agent should be loaded at bind-time.
7549                    boolean needsInfo = mProfilerInfo.profileFile != null
7550                            || mProfilerInfo.attachAgentDuringBind;
7551                    profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7552                    if (mProfilerInfo.agent != null) {
7553                        preBindAgent = mProfilerInfo.agent;
7554                    }
7555                }
7556            } else if (app.instr != null && app.instr.mProfileFile != null) {
7557                profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7558                        null, false);
7559            }
7560            if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
7561                // We need to do a debuggable check here. See setAgentApp for why the check is
7562                // postponed to here.
7563                if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
7564                    String agent = mAppAgentMap.get(processName);
7565                    // Do not overwrite already requested agent.
7566                    if (profilerInfo == null) {
7567                        profilerInfo = new ProfilerInfo(null, null, 0, false, false,
7568                                mAppAgentMap.get(processName), true);
7569                    } else if (profilerInfo.agent == null) {
7570                        profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
7571                    }
7572                }
7573            }
7574
7575            if (profilerInfo != null && profilerInfo.profileFd != null) {
7576                profilerInfo.profileFd = profilerInfo.profileFd.dup();
7577            }
7578
7579            // We deprecated Build.SERIAL and it is not accessible to
7580            // apps that target the v2 security sandbox and to apps that
7581            // target APIs higher than O MR1. Since access to the serial
7582            // is now behind a permission we push down the value.
7583            final String buildSerial = (appInfo.targetSandboxVersion < 2
7584                    && appInfo.targetSdkVersion <= Build.VERSION_CODES.O_MR1)
7585                            ? sTheRealBuildSerial : Build.UNKNOWN;
7586
7587            // Check if this is a secondary process that should be incorporated into some
7588            // currently active instrumentation.  (Note we do this AFTER all of the profiling
7589            // stuff above because profiling can currently happen only in the primary
7590            // instrumentation process.)
7591            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7592                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7593                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7594                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7595                        if (aInstr.mTargetProcesses.length == 0) {
7596                            // This is the wildcard mode, where every process brought up for
7597                            // the target instrumentation should be included.
7598                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7599                                app.instr = aInstr;
7600                                aInstr.mRunningProcesses.add(app);
7601                            }
7602                        } else {
7603                            for (String proc : aInstr.mTargetProcesses) {
7604                                if (proc.equals(app.processName)) {
7605                                    app.instr = aInstr;
7606                                    aInstr.mRunningProcesses.add(app);
7607                                    break;
7608                                }
7609                            }
7610                        }
7611                    }
7612                }
7613            }
7614
7615            // If we were asked to attach an agent on startup, do so now, before we're binding
7616            // application code.
7617            if (preBindAgent != null) {
7618                thread.attachAgent(preBindAgent);
7619            }
7620
7621
7622            // Figure out whether the app needs to run in autofill compat mode.
7623            boolean isAutofillCompatEnabled = false;
7624            if (UserHandle.getAppId(app.info.uid) >= Process.FIRST_APPLICATION_UID) {
7625                final AutofillManagerInternal afm = LocalServices.getService(
7626                        AutofillManagerInternal.class);
7627                if (afm != null) {
7628                    isAutofillCompatEnabled = afm.isCompatibilityModeRequested(
7629                            app.info.packageName, app.info.versionCode, app.userId);
7630                }
7631            }
7632
7633            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7634            mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
7635            if (app.isolatedEntryPoint != null) {
7636                // This is an isolated process which should just call an entry point instead of
7637                // being bound to an application.
7638                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7639            } else if (app.instr != null) {
7640                thread.bindApplication(processName, appInfo, providers,
7641                        app.instr.mClass,
7642                        profilerInfo, app.instr.mArguments,
7643                        app.instr.mWatcher,
7644                        app.instr.mUiAutomationConnection, testMode,
7645                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7646                        isRestrictedBackupMode || !normalMode, app.persistent,
7647                        new Configuration(getGlobalConfiguration()), app.compat,
7648                        getCommonServicesLocked(app.isolated),
7649                        mCoreSettingsObserver.getCoreSettingsLocked(),
7650                        buildSerial, isAutofillCompatEnabled);
7651            } else {
7652                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7653                        null, null, null, testMode,
7654                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7655                        isRestrictedBackupMode || !normalMode, app.persistent,
7656                        new Configuration(getGlobalConfiguration()), app.compat,
7657                        getCommonServicesLocked(app.isolated),
7658                        mCoreSettingsObserver.getCoreSettingsLocked(),
7659                        buildSerial, isAutofillCompatEnabled);
7660            }
7661
7662            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7663            updateLruProcessLocked(app, false, null);
7664            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7665            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7666        } catch (Exception e) {
7667            // todo: Yikes!  What should we do?  For now we will try to
7668            // start another process, but that could easily get us in
7669            // an infinite loop of restarting processes...
7670            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7671
7672            app.resetPackageList(mProcessStats);
7673            app.unlinkDeathRecipient();
7674            startProcessLocked(app, "bind fail", processName);
7675            return false;
7676        }
7677
7678        // Remove this record from the list of starting applications.
7679        mPersistentStartingProcesses.remove(app);
7680        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7681                "Attach application locked removing on hold: " + app);
7682        mProcessesOnHold.remove(app);
7683
7684        boolean badApp = false;
7685        boolean didSomething = false;
7686
7687        // See if the top visible activity is waiting to run in this process...
7688        if (normalMode) {
7689            try {
7690                if (mStackSupervisor.attachApplicationLocked(app)) {
7691                    didSomething = true;
7692                }
7693            } catch (Exception e) {
7694                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7695                badApp = true;
7696            }
7697        }
7698
7699        // Find any services that should be running in this process...
7700        if (!badApp) {
7701            try {
7702                didSomething |= mServices.attachApplicationLocked(app, processName);
7703                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7704            } catch (Exception e) {
7705                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7706                badApp = true;
7707            }
7708        }
7709
7710        // Check if a next-broadcast receiver is in this process...
7711        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7712            try {
7713                didSomething |= sendPendingBroadcastsLocked(app);
7714                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7715            } catch (Exception e) {
7716                // If the app died trying to launch the receiver we declare it 'bad'
7717                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7718                badApp = true;
7719            }
7720        }
7721
7722        // Check whether the next backup agent is in this process...
7723        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7724            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7725                    "New app is backup target, launching agent for " + app);
7726            notifyPackageUse(mBackupTarget.appInfo.packageName,
7727                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7728            try {
7729                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7730                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7731                        mBackupTarget.backupMode);
7732            } catch (Exception e) {
7733                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7734                badApp = true;
7735            }
7736        }
7737
7738        if (badApp) {
7739            app.kill("error during init", true);
7740            handleAppDiedLocked(app, false, true);
7741            return false;
7742        }
7743
7744        if (!didSomething) {
7745            updateOomAdjLocked();
7746            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7747        }
7748
7749        return true;
7750    }
7751
7752    @Override
7753    public final void attachApplication(IApplicationThread thread, long startSeq) {
7754        synchronized (this) {
7755            int callingPid = Binder.getCallingPid();
7756            final int callingUid = Binder.getCallingUid();
7757            final long origId = Binder.clearCallingIdentity();
7758            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
7759            Binder.restoreCallingIdentity(origId);
7760        }
7761    }
7762
7763    @Override
7764    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7765        final long origId = Binder.clearCallingIdentity();
7766        synchronized (this) {
7767            ActivityStack stack = ActivityRecord.getStackLocked(token);
7768            if (stack != null) {
7769                ActivityRecord r =
7770                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7771                                false /* processPausingActivities */, config);
7772                if (stopProfiling) {
7773                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
7774                        clearProfilerLocked();
7775                    }
7776                }
7777            }
7778        }
7779        Binder.restoreCallingIdentity(origId);
7780    }
7781
7782    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7783        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7784                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7785    }
7786
7787    void enableScreenAfterBoot() {
7788        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7789                SystemClock.uptimeMillis());
7790        mWindowManager.enableScreenAfterBoot();
7791
7792        synchronized (this) {
7793            updateEventDispatchingLocked();
7794        }
7795    }
7796
7797    @Override
7798    public void showBootMessage(final CharSequence msg, final boolean always) {
7799        if (Binder.getCallingUid() != myUid()) {
7800            throw new SecurityException();
7801        }
7802        mWindowManager.showBootMessage(msg, always);
7803    }
7804
7805    @Override
7806    public void keyguardGoingAway(int flags) {
7807        enforceNotIsolatedCaller("keyguardGoingAway");
7808        final long token = Binder.clearCallingIdentity();
7809        try {
7810            synchronized (this) {
7811                mKeyguardController.keyguardGoingAway(flags);
7812            }
7813        } finally {
7814            Binder.restoreCallingIdentity(token);
7815        }
7816    }
7817
7818    /**
7819     * @return whther the keyguard is currently locked.
7820     */
7821    boolean isKeyguardLocked() {
7822        return mKeyguardController.isKeyguardLocked();
7823    }
7824
7825    final void finishBooting() {
7826        synchronized (this) {
7827            if (!mBootAnimationComplete) {
7828                mCallFinishBooting = true;
7829                return;
7830            }
7831            mCallFinishBooting = false;
7832        }
7833
7834        ArraySet<String> completedIsas = new ArraySet<String>();
7835        for (String abi : Build.SUPPORTED_ABIS) {
7836            zygoteProcess.establishZygoteConnectionForAbi(abi);
7837            final String instructionSet = VMRuntime.getInstructionSet(abi);
7838            if (!completedIsas.contains(instructionSet)) {
7839                try {
7840                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7841                } catch (InstallerException e) {
7842                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7843                            e.getMessage() +")");
7844                }
7845                completedIsas.add(instructionSet);
7846            }
7847        }
7848
7849        IntentFilter pkgFilter = new IntentFilter();
7850        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7851        pkgFilter.addDataScheme("package");
7852        mContext.registerReceiver(new BroadcastReceiver() {
7853            @Override
7854            public void onReceive(Context context, Intent intent) {
7855                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7856                if (pkgs != null) {
7857                    for (String pkg : pkgs) {
7858                        synchronized (ActivityManagerService.this) {
7859                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7860                                    0, "query restart")) {
7861                                setResultCode(Activity.RESULT_OK);
7862                                return;
7863                            }
7864                        }
7865                    }
7866                }
7867            }
7868        }, pkgFilter);
7869
7870        IntentFilter dumpheapFilter = new IntentFilter();
7871        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7872        mContext.registerReceiver(new BroadcastReceiver() {
7873            @Override
7874            public void onReceive(Context context, Intent intent) {
7875                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7876                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7877                } else {
7878                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7879                }
7880            }
7881        }, dumpheapFilter);
7882
7883        // Let system services know.
7884        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7885
7886        synchronized (this) {
7887            // Ensure that any processes we had put on hold are now started
7888            // up.
7889            final int NP = mProcessesOnHold.size();
7890            if (NP > 0) {
7891                ArrayList<ProcessRecord> procs =
7892                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7893                for (int ip=0; ip<NP; ip++) {
7894                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7895                            + procs.get(ip));
7896                    startProcessLocked(procs.get(ip), "on-hold", null);
7897                }
7898            }
7899            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7900                return;
7901            }
7902            // Start looking for apps that are abusing wake locks.
7903            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7904            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7905            // Tell anyone interested that we are done booting!
7906            SystemProperties.set("sys.boot_completed", "1");
7907
7908            // And trigger dev.bootcomplete if we are not showing encryption progress
7909            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7910                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7911                SystemProperties.set("dev.bootcomplete", "1");
7912            }
7913            mUserController.sendBootCompleted(
7914                    new IIntentReceiver.Stub() {
7915                        @Override
7916                        public void performReceive(Intent intent, int resultCode,
7917                                String data, Bundle extras, boolean ordered,
7918                                boolean sticky, int sendingUser) {
7919                            synchronized (ActivityManagerService.this) {
7920                                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
7921                            }
7922                        }
7923                    });
7924            mUserController.scheduleStartProfiles();
7925        }
7926    }
7927
7928    @Override
7929    public void bootAnimationComplete() {
7930        final boolean callFinishBooting;
7931        synchronized (this) {
7932            callFinishBooting = mCallFinishBooting;
7933            mBootAnimationComplete = true;
7934        }
7935        if (callFinishBooting) {
7936            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7937            finishBooting();
7938            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7939        }
7940    }
7941
7942    final void ensureBootCompleted() {
7943        boolean booting;
7944        boolean enableScreen;
7945        synchronized (this) {
7946            booting = mBooting;
7947            mBooting = false;
7948            enableScreen = !mBooted;
7949            mBooted = true;
7950        }
7951
7952        if (booting) {
7953            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7954            finishBooting();
7955            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7956        }
7957
7958        if (enableScreen) {
7959            enableScreenAfterBoot();
7960        }
7961    }
7962
7963    @Override
7964    public final void activityResumed(IBinder token) {
7965        final long origId = Binder.clearCallingIdentity();
7966        synchronized(this) {
7967            ActivityRecord.activityResumedLocked(token);
7968            mWindowManager.notifyAppResumedFinished(token);
7969        }
7970        Binder.restoreCallingIdentity(origId);
7971    }
7972
7973    @Override
7974    public final void activityPaused(IBinder token) {
7975        final long origId = Binder.clearCallingIdentity();
7976        synchronized(this) {
7977            ActivityStack stack = ActivityRecord.getStackLocked(token);
7978            if (stack != null) {
7979                stack.activityPausedLocked(token, false);
7980            }
7981        }
7982        Binder.restoreCallingIdentity(origId);
7983    }
7984
7985    @Override
7986    public final void activityStopped(IBinder token, Bundle icicle,
7987            PersistableBundle persistentState, CharSequence description) {
7988        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7989
7990        // Refuse possible leaked file descriptors
7991        if (icicle != null && icicle.hasFileDescriptors()) {
7992            throw new IllegalArgumentException("File descriptors passed in Bundle");
7993        }
7994
7995        final long origId = Binder.clearCallingIdentity();
7996
7997        synchronized (this) {
7998            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7999            if (r != null) {
8000                r.activityStoppedLocked(icicle, persistentState, description);
8001            }
8002        }
8003
8004        trimApplications();
8005
8006        Binder.restoreCallingIdentity(origId);
8007    }
8008
8009    @Override
8010    public final void activityDestroyed(IBinder token) {
8011        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
8012        synchronized (this) {
8013            ActivityStack stack = ActivityRecord.getStackLocked(token);
8014            if (stack != null) {
8015                stack.activityDestroyedLocked(token, "activityDestroyed");
8016            }
8017        }
8018    }
8019
8020    @Override
8021    public final void activityRelaunched(IBinder token) {
8022        final long origId = Binder.clearCallingIdentity();
8023        synchronized (this) {
8024            mStackSupervisor.activityRelaunchedLocked(token);
8025        }
8026        Binder.restoreCallingIdentity(origId);
8027    }
8028
8029    @Override
8030    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
8031            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
8032        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
8033                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
8034        synchronized (this) {
8035            ActivityRecord record = ActivityRecord.isInStackLocked(token);
8036            if (record == null) {
8037                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
8038                        + "found for: " + token);
8039            }
8040            record.setSizeConfigurations(horizontalSizeConfiguration,
8041                    verticalSizeConfigurations, smallestSizeConfigurations);
8042        }
8043    }
8044
8045    @Override
8046    public final void notifyLaunchTaskBehindComplete(IBinder token) {
8047        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
8048    }
8049
8050    @Override
8051    public final void notifyEnterAnimationComplete(IBinder token) {
8052        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
8053    }
8054
8055    @Override
8056    public String getCallingPackage(IBinder token) {
8057        synchronized (this) {
8058            ActivityRecord r = getCallingRecordLocked(token);
8059            return r != null ? r.info.packageName : null;
8060        }
8061    }
8062
8063    @Override
8064    public ComponentName getCallingActivity(IBinder token) {
8065        synchronized (this) {
8066            ActivityRecord r = getCallingRecordLocked(token);
8067            return r != null ? r.intent.getComponent() : null;
8068        }
8069    }
8070
8071    private ActivityRecord getCallingRecordLocked(IBinder token) {
8072        ActivityRecord r = ActivityRecord.isInStackLocked(token);
8073        if (r == null) {
8074            return null;
8075        }
8076        return r.resultTo;
8077    }
8078
8079    @Override
8080    public ComponentName getActivityClassForToken(IBinder token) {
8081        synchronized(this) {
8082            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8083            if (r == null) {
8084                return null;
8085            }
8086            return r.intent.getComponent();
8087        }
8088    }
8089
8090    @Override
8091    public String getPackageForToken(IBinder token) {
8092        synchronized(this) {
8093            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8094            if (r == null) {
8095                return null;
8096            }
8097            return r.packageName;
8098        }
8099    }
8100
8101    @Override
8102    public boolean isRootVoiceInteraction(IBinder token) {
8103        synchronized(this) {
8104            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8105            if (r == null) {
8106                return false;
8107            }
8108            return r.rootVoiceInteraction;
8109        }
8110    }
8111
8112    @Override
8113    public IIntentSender getIntentSender(int type,
8114            String packageName, IBinder token, String resultWho,
8115            int requestCode, Intent[] intents, String[] resolvedTypes,
8116            int flags, Bundle bOptions, int userId) {
8117        enforceNotIsolatedCaller("getIntentSender");
8118        // Refuse possible leaked file descriptors
8119        if (intents != null) {
8120            if (intents.length < 1) {
8121                throw new IllegalArgumentException("Intents array length must be >= 1");
8122            }
8123            for (int i=0; i<intents.length; i++) {
8124                Intent intent = intents[i];
8125                if (intent != null) {
8126                    if (intent.hasFileDescriptors()) {
8127                        throw new IllegalArgumentException("File descriptors passed in Intent");
8128                    }
8129                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
8130                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
8131                        throw new IllegalArgumentException(
8132                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
8133                    }
8134                    intents[i] = new Intent(intent);
8135                }
8136            }
8137            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
8138                throw new IllegalArgumentException(
8139                        "Intent array length does not match resolvedTypes length");
8140            }
8141        }
8142        if (bOptions != null) {
8143            if (bOptions.hasFileDescriptors()) {
8144                throw new IllegalArgumentException("File descriptors passed in options");
8145            }
8146        }
8147
8148        synchronized(this) {
8149            int callingUid = Binder.getCallingUid();
8150            int origUserId = userId;
8151            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8152                    type == ActivityManager.INTENT_SENDER_BROADCAST,
8153                    ALLOW_NON_FULL, "getIntentSender", null);
8154            if (origUserId == UserHandle.USER_CURRENT) {
8155                // We don't want to evaluate this until the pending intent is
8156                // actually executed.  However, we do want to always do the
8157                // security checking for it above.
8158                userId = UserHandle.USER_CURRENT;
8159            }
8160            try {
8161                if (callingUid != 0 && callingUid != SYSTEM_UID) {
8162                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
8163                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
8164                    if (!UserHandle.isSameApp(callingUid, uid)) {
8165                        String msg = "Permission Denial: getIntentSender() from pid="
8166                            + Binder.getCallingPid()
8167                            + ", uid=" + Binder.getCallingUid()
8168                            + ", (need uid=" + uid + ")"
8169                            + " is not allowed to send as package " + packageName;
8170                        Slog.w(TAG, msg);
8171                        throw new SecurityException(msg);
8172                    }
8173                }
8174
8175                return getIntentSenderLocked(type, packageName, callingUid, userId,
8176                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
8177
8178            } catch (RemoteException e) {
8179                throw new SecurityException(e);
8180            }
8181        }
8182    }
8183
8184    IIntentSender getIntentSenderLocked(int type, String packageName,
8185            int callingUid, int userId, IBinder token, String resultWho,
8186            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
8187            Bundle bOptions) {
8188        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
8189        ActivityRecord activity = null;
8190        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8191            activity = ActivityRecord.isInStackLocked(token);
8192            if (activity == null) {
8193                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
8194                return null;
8195            }
8196            if (activity.finishing) {
8197                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
8198                return null;
8199            }
8200        }
8201
8202        // We're going to be splicing together extras before sending, so we're
8203        // okay poking into any contained extras.
8204        if (intents != null) {
8205            for (int i = 0; i < intents.length; i++) {
8206                intents[i].setDefusable(true);
8207            }
8208        }
8209        Bundle.setDefusable(bOptions, true);
8210
8211        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
8212        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
8213        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
8214        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
8215                |PendingIntent.FLAG_UPDATE_CURRENT);
8216
8217        PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity,
8218                resultWho, requestCode, intents, resolvedTypes, flags,
8219                SafeActivityOptions.fromBundle(bOptions), userId);
8220        WeakReference<PendingIntentRecord> ref;
8221        ref = mIntentSenderRecords.get(key);
8222        PendingIntentRecord rec = ref != null ? ref.get() : null;
8223        if (rec != null) {
8224            if (!cancelCurrent) {
8225                if (updateCurrent) {
8226                    if (rec.key.requestIntent != null) {
8227                        rec.key.requestIntent.replaceExtras(intents != null ?
8228                                intents[intents.length - 1] : null);
8229                    }
8230                    if (intents != null) {
8231                        intents[intents.length-1] = rec.key.requestIntent;
8232                        rec.key.allIntents = intents;
8233                        rec.key.allResolvedTypes = resolvedTypes;
8234                    } else {
8235                        rec.key.allIntents = null;
8236                        rec.key.allResolvedTypes = null;
8237                    }
8238                }
8239                return rec;
8240            }
8241            makeIntentSenderCanceledLocked(rec);
8242            mIntentSenderRecords.remove(key);
8243        }
8244        if (noCreate) {
8245            return rec;
8246        }
8247        rec = new PendingIntentRecord(this, key, callingUid);
8248        mIntentSenderRecords.put(key, rec.ref);
8249        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8250            if (activity.pendingResults == null) {
8251                activity.pendingResults
8252                        = new HashSet<WeakReference<PendingIntentRecord>>();
8253            }
8254            activity.pendingResults.add(rec.ref);
8255        }
8256        return rec;
8257    }
8258
8259    @Override
8260    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
8261            Intent intent, String resolvedType,
8262            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
8263        if (target instanceof PendingIntentRecord) {
8264            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
8265                    whitelistToken, finishedReceiver, requiredPermission, options);
8266        } else {
8267            if (intent == null) {
8268                // Weird case: someone has given us their own custom IIntentSender, and now
8269                // they have someone else trying to send to it but of course this isn't
8270                // really a PendingIntent, so there is no base Intent, and the caller isn't
8271                // supplying an Intent... but we never want to dispatch a null Intent to
8272                // a receiver, so um...  let's make something up.
8273                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
8274                intent = new Intent(Intent.ACTION_MAIN);
8275            }
8276            try {
8277                target.send(code, intent, resolvedType, whitelistToken, null,
8278                        requiredPermission, options);
8279            } catch (RemoteException e) {
8280            }
8281            // Platform code can rely on getting a result back when the send is done, but if
8282            // this intent sender is from outside of the system we can't rely on it doing that.
8283            // So instead we don't give it the result receiver, and instead just directly
8284            // report the finish immediately.
8285            if (finishedReceiver != null) {
8286                try {
8287                    finishedReceiver.performReceive(intent, 0,
8288                            null, null, false, false, UserHandle.getCallingUserId());
8289                } catch (RemoteException e) {
8290                }
8291            }
8292            return 0;
8293        }
8294    }
8295
8296    @Override
8297    public void cancelIntentSender(IIntentSender sender) {
8298        if (!(sender instanceof PendingIntentRecord)) {
8299            return;
8300        }
8301        synchronized(this) {
8302            PendingIntentRecord rec = (PendingIntentRecord)sender;
8303            try {
8304                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
8305                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
8306                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
8307                    String msg = "Permission Denial: cancelIntentSender() from pid="
8308                        + Binder.getCallingPid()
8309                        + ", uid=" + Binder.getCallingUid()
8310                        + " is not allowed to cancel package "
8311                        + rec.key.packageName;
8312                    Slog.w(TAG, msg);
8313                    throw new SecurityException(msg);
8314                }
8315            } catch (RemoteException e) {
8316                throw new SecurityException(e);
8317            }
8318            cancelIntentSenderLocked(rec, true);
8319        }
8320    }
8321
8322    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
8323        makeIntentSenderCanceledLocked(rec);
8324        mIntentSenderRecords.remove(rec.key);
8325        if (cleanActivity && rec.key.activity != null) {
8326            rec.key.activity.pendingResults.remove(rec.ref);
8327        }
8328    }
8329
8330    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
8331        rec.canceled = true;
8332        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
8333        if (callbacks != null) {
8334            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
8335        }
8336    }
8337
8338    @Override
8339    public String getPackageForIntentSender(IIntentSender pendingResult) {
8340        if (!(pendingResult instanceof PendingIntentRecord)) {
8341            return null;
8342        }
8343        try {
8344            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8345            return res.key.packageName;
8346        } catch (ClassCastException e) {
8347        }
8348        return null;
8349    }
8350
8351    @Override
8352    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
8353        if (!(sender instanceof PendingIntentRecord)) {
8354            return;
8355        }
8356        synchronized(this) {
8357            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
8358        }
8359    }
8360
8361    @Override
8362    public void unregisterIntentSenderCancelListener(IIntentSender sender,
8363            IResultReceiver receiver) {
8364        if (!(sender instanceof PendingIntentRecord)) {
8365            return;
8366        }
8367        synchronized(this) {
8368            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
8369        }
8370    }
8371
8372    @Override
8373    public int getUidForIntentSender(IIntentSender sender) {
8374        if (sender instanceof PendingIntentRecord) {
8375            try {
8376                PendingIntentRecord res = (PendingIntentRecord)sender;
8377                return res.uid;
8378            } catch (ClassCastException e) {
8379            }
8380        }
8381        return -1;
8382    }
8383
8384    @Override
8385    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
8386        if (!(pendingResult instanceof PendingIntentRecord)) {
8387            return false;
8388        }
8389        try {
8390            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8391            if (res.key.allIntents == null) {
8392                return false;
8393            }
8394            for (int i=0; i<res.key.allIntents.length; i++) {
8395                Intent intent = res.key.allIntents[i];
8396                if (intent.getPackage() != null && intent.getComponent() != null) {
8397                    return false;
8398                }
8399            }
8400            return true;
8401        } catch (ClassCastException e) {
8402        }
8403        return false;
8404    }
8405
8406    @Override
8407    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
8408        if (!(pendingResult instanceof PendingIntentRecord)) {
8409            return false;
8410        }
8411        try {
8412            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8413            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
8414                return true;
8415            }
8416            return false;
8417        } catch (ClassCastException e) {
8418        }
8419        return false;
8420    }
8421
8422    @Override
8423    public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
8424        if (pendingResult instanceof PendingIntentRecord) {
8425            final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
8426            return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
8427        }
8428        return false;
8429    }
8430
8431    @Override
8432    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
8433        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
8434                "getIntentForIntentSender()");
8435        if (!(pendingResult instanceof PendingIntentRecord)) {
8436            return null;
8437        }
8438        try {
8439            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8440            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
8441        } catch (ClassCastException e) {
8442        }
8443        return null;
8444    }
8445
8446    @Override
8447    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
8448        if (!(pendingResult instanceof PendingIntentRecord)) {
8449            return null;
8450        }
8451        try {
8452            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8453            synchronized (this) {
8454                return getTagForIntentSenderLocked(res, prefix);
8455            }
8456        } catch (ClassCastException e) {
8457        }
8458        return null;
8459    }
8460
8461    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
8462        final Intent intent = res.key.requestIntent;
8463        if (intent != null) {
8464            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
8465                    || res.lastTagPrefix.equals(prefix))) {
8466                return res.lastTag;
8467            }
8468            res.lastTagPrefix = prefix;
8469            final StringBuilder sb = new StringBuilder(128);
8470            if (prefix != null) {
8471                sb.append(prefix);
8472            }
8473            if (intent.getAction() != null) {
8474                sb.append(intent.getAction());
8475            } else if (intent.getComponent() != null) {
8476                intent.getComponent().appendShortString(sb);
8477            } else {
8478                sb.append("?");
8479            }
8480            return res.lastTag = sb.toString();
8481        }
8482        return null;
8483    }
8484
8485    @Override
8486    public void setProcessLimit(int max) {
8487        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8488                "setProcessLimit()");
8489        synchronized (this) {
8490            mConstants.setOverrideMaxCachedProcesses(max);
8491        }
8492        trimApplications();
8493    }
8494
8495    @Override
8496    public int getProcessLimit() {
8497        synchronized (this) {
8498            return mConstants.getOverrideMaxCachedProcesses();
8499        }
8500    }
8501
8502    void importanceTokenDied(ImportanceToken token) {
8503        synchronized (ActivityManagerService.this) {
8504            synchronized (mPidsSelfLocked) {
8505                ImportanceToken cur
8506                    = mImportantProcesses.get(token.pid);
8507                if (cur != token) {
8508                    return;
8509                }
8510                mImportantProcesses.remove(token.pid);
8511                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
8512                if (pr == null) {
8513                    return;
8514                }
8515                pr.forcingToImportant = null;
8516                updateProcessForegroundLocked(pr, false, false);
8517            }
8518            updateOomAdjLocked();
8519        }
8520    }
8521
8522    @Override
8523    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8524        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8525                "setProcessImportant()");
8526        synchronized(this) {
8527            boolean changed = false;
8528
8529            synchronized (mPidsSelfLocked) {
8530                ProcessRecord pr = mPidsSelfLocked.get(pid);
8531                if (pr == null && isForeground) {
8532                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8533                    return;
8534                }
8535                ImportanceToken oldToken = mImportantProcesses.get(pid);
8536                if (oldToken != null) {
8537                    oldToken.token.unlinkToDeath(oldToken, 0);
8538                    mImportantProcesses.remove(pid);
8539                    if (pr != null) {
8540                        pr.forcingToImportant = null;
8541                    }
8542                    changed = true;
8543                }
8544                if (isForeground && token != null) {
8545                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8546                        @Override
8547                        public void binderDied() {
8548                            importanceTokenDied(this);
8549                        }
8550                    };
8551                    try {
8552                        token.linkToDeath(newToken, 0);
8553                        mImportantProcesses.put(pid, newToken);
8554                        pr.forcingToImportant = newToken;
8555                        changed = true;
8556                    } catch (RemoteException e) {
8557                        // If the process died while doing this, we will later
8558                        // do the cleanup with the process death link.
8559                    }
8560                }
8561            }
8562
8563            if (changed) {
8564                updateOomAdjLocked();
8565            }
8566        }
8567    }
8568
8569    @Override
8570    public boolean isAppForeground(int uid) throws RemoteException {
8571        synchronized (this) {
8572            UidRecord uidRec = mActiveUids.get(uid);
8573            if (uidRec == null || uidRec.idle) {
8574                return false;
8575            }
8576            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8577        }
8578    }
8579
8580    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8581    // be guarded by permission checking.
8582    int getUidState(int uid) {
8583        synchronized (this) {
8584            return getUidStateLocked(uid);
8585        }
8586    }
8587
8588    int getUidStateLocked(int uid) {
8589        UidRecord uidRec = mActiveUids.get(uid);
8590        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8591    }
8592
8593    @Override
8594    public boolean isInMultiWindowMode(IBinder token) {
8595        final long origId = Binder.clearCallingIdentity();
8596        try {
8597            synchronized(this) {
8598                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8599                if (r == null) {
8600                    return false;
8601                }
8602                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8603                return r.inMultiWindowMode();
8604            }
8605        } finally {
8606            Binder.restoreCallingIdentity(origId);
8607        }
8608    }
8609
8610    @Override
8611    public boolean isInPictureInPictureMode(IBinder token) {
8612        final long origId = Binder.clearCallingIdentity();
8613        try {
8614            synchronized(this) {
8615                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8616            }
8617        } finally {
8618            Binder.restoreCallingIdentity(origId);
8619        }
8620    }
8621
8622    private boolean isInPictureInPictureMode(ActivityRecord r) {
8623        if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8624                || r.getStack().isInStackLocked(r) == null) {
8625            return false;
8626        }
8627
8628        // If we are animating to fullscreen then we have already dispatched the PIP mode
8629        // changed, so we should reflect that check here as well.
8630        final PinnedActivityStack stack = r.getStack();
8631        final PinnedStackWindowController windowController = stack.getWindowContainerController();
8632        return !windowController.isAnimatingBoundsToFullscreen();
8633    }
8634
8635    @Override
8636    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8637        final long origId = Binder.clearCallingIdentity();
8638        try {
8639            synchronized(this) {
8640                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8641                        "enterPictureInPictureMode", token, params);
8642
8643                // If the activity is already in picture in picture mode, then just return early
8644                if (isInPictureInPictureMode(r)) {
8645                    return true;
8646                }
8647
8648                // Activity supports picture-in-picture, now check that we can enter PiP at this
8649                // point, if it is
8650                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8651                        false /* beforeStopping */)) {
8652                    return false;
8653                }
8654
8655                final Runnable enterPipRunnable = () -> {
8656                    // Only update the saved args from the args that are set
8657                    r.pictureInPictureArgs.copyOnlySet(params);
8658                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8659                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8660                    // Adjust the source bounds by the insets for the transition down
8661                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8662                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8663                            "enterPictureInPictureMode");
8664                    final PinnedActivityStack stack = r.getStack();
8665                    stack.setPictureInPictureAspectRatio(aspectRatio);
8666                    stack.setPictureInPictureActions(actions);
8667                    MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
8668                            r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
8669                    logPictureInPictureArgs(params);
8670                };
8671
8672                if (isKeyguardLocked()) {
8673                    // If the keyguard is showing or occluded, then try and dismiss it before
8674                    // entering picture-in-picture (this will prompt the user to authenticate if the
8675                    // device is currently locked).
8676                    try {
8677                        dismissKeyguard(token, new KeyguardDismissCallback() {
8678                            @Override
8679                            public void onDismissSucceeded() throws RemoteException {
8680                                mHandler.post(enterPipRunnable);
8681                            }
8682                        }, null /* message */);
8683                    } catch (RemoteException e) {
8684                        // Local call
8685                    }
8686                } else {
8687                    // Enter picture in picture immediately otherwise
8688                    enterPipRunnable.run();
8689                }
8690                return true;
8691            }
8692        } finally {
8693            Binder.restoreCallingIdentity(origId);
8694        }
8695    }
8696
8697    @Override
8698    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8699        final long origId = Binder.clearCallingIdentity();
8700        try {
8701            synchronized(this) {
8702                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8703                        "setPictureInPictureParams", token, params);
8704
8705                // Only update the saved args from the args that are set
8706                r.pictureInPictureArgs.copyOnlySet(params);
8707                if (r.inPinnedWindowingMode()) {
8708                    // If the activity is already in picture-in-picture, update the pinned stack now
8709                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8710                    // be used the next time the activity enters PiP
8711                    final PinnedActivityStack stack = r.getStack();
8712                    if (!stack.isAnimatingBoundsToFullscreen()) {
8713                        stack.setPictureInPictureAspectRatio(
8714                                r.pictureInPictureArgs.getAspectRatio());
8715                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8716                    }
8717                }
8718                logPictureInPictureArgs(params);
8719            }
8720        } finally {
8721            Binder.restoreCallingIdentity(origId);
8722        }
8723    }
8724
8725    @Override
8726    public int getMaxNumPictureInPictureActions(IBinder token) {
8727        // Currently, this is a static constant, but later, we may change this to be dependent on
8728        // the context of the activity
8729        return 3;
8730    }
8731
8732    private void logPictureInPictureArgs(PictureInPictureParams params) {
8733        if (params.hasSetActions()) {
8734            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8735                    params.getActions().size());
8736        }
8737        if (params.hasSetAspectRatio()) {
8738            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8739            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8740            MetricsLogger.action(lm);
8741        }
8742    }
8743
8744    /**
8745     * Checks the state of the system and the activity associated with the given {@param token} to
8746     * verify that picture-in-picture is supported for that activity.
8747     *
8748     * @return the activity record for the given {@param token} if all the checks pass.
8749     */
8750    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8751            IBinder token, PictureInPictureParams params) {
8752        if (!mSupportsPictureInPicture) {
8753            throw new IllegalStateException(caller
8754                    + ": Device doesn't support picture-in-picture mode.");
8755        }
8756
8757        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8758        if (r == null) {
8759            throw new IllegalStateException(caller
8760                    + ": Can't find activity for token=" + token);
8761        }
8762
8763        if (!r.supportsPictureInPicture()) {
8764            throw new IllegalStateException(caller
8765                    + ": Current activity does not support picture-in-picture.");
8766        }
8767
8768        if (params.hasSetAspectRatio()
8769                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8770                        params.getAspectRatio())) {
8771            final float minAspectRatio = mContext.getResources().getFloat(
8772                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8773            final float maxAspectRatio = mContext.getResources().getFloat(
8774                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8775            throw new IllegalArgumentException(String.format(caller
8776                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8777                            minAspectRatio, maxAspectRatio));
8778        }
8779
8780        // Truncate the number of actions if necessary
8781        params.truncateActions(getMaxNumPictureInPictureActions(token));
8782
8783        return r;
8784    }
8785
8786    // =========================================================
8787    // PROCESS INFO
8788    // =========================================================
8789
8790    static class ProcessInfoService extends IProcessInfoService.Stub {
8791        final ActivityManagerService mActivityManagerService;
8792        ProcessInfoService(ActivityManagerService activityManagerService) {
8793            mActivityManagerService = activityManagerService;
8794        }
8795
8796        @Override
8797        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8798            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8799                    /*in*/ pids, /*out*/ states, null);
8800        }
8801
8802        @Override
8803        public void getProcessStatesAndOomScoresFromPids(
8804                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8805            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8806                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8807        }
8808    }
8809
8810    /**
8811     * For each PID in the given input array, write the current process state
8812     * for that process into the states array, or -1 to indicate that no
8813     * process with the given PID exists. If scores array is provided, write
8814     * the oom score for the process into the scores array, with INVALID_ADJ
8815     * indicating the PID doesn't exist.
8816     */
8817    public void getProcessStatesAndOomScoresForPIDs(
8818            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8819        if (scores != null) {
8820            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8821                    "getProcessStatesAndOomScoresForPIDs()");
8822        }
8823
8824        if (pids == null) {
8825            throw new NullPointerException("pids");
8826        } else if (states == null) {
8827            throw new NullPointerException("states");
8828        } else if (pids.length != states.length) {
8829            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8830        } else if (scores != null && pids.length != scores.length) {
8831            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8832        }
8833
8834        synchronized (mPidsSelfLocked) {
8835            for (int i = 0; i < pids.length; i++) {
8836                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8837                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8838                        pr.curProcState;
8839                if (scores != null) {
8840                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8841                }
8842            }
8843        }
8844    }
8845
8846    // =========================================================
8847    // PERMISSIONS
8848    // =========================================================
8849
8850    static class PermissionController extends IPermissionController.Stub {
8851        ActivityManagerService mActivityManagerService;
8852        PermissionController(ActivityManagerService activityManagerService) {
8853            mActivityManagerService = activityManagerService;
8854        }
8855
8856        @Override
8857        public boolean checkPermission(String permission, int pid, int uid) {
8858            return mActivityManagerService.checkPermission(permission, pid,
8859                    uid) == PackageManager.PERMISSION_GRANTED;
8860        }
8861
8862        @Override
8863        public String[] getPackagesForUid(int uid) {
8864            return mActivityManagerService.mContext.getPackageManager()
8865                    .getPackagesForUid(uid);
8866        }
8867
8868        @Override
8869        public boolean isRuntimePermission(String permission) {
8870            try {
8871                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8872                        .getPermissionInfo(permission, 0);
8873                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8874                        == PermissionInfo.PROTECTION_DANGEROUS;
8875            } catch (NameNotFoundException nnfe) {
8876                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8877            }
8878            return false;
8879        }
8880
8881        @Override
8882        public int getPackageUid(String packageName, int flags) {
8883            try {
8884                return mActivityManagerService.mContext.getPackageManager()
8885                        .getPackageUid(packageName, flags);
8886            } catch (NameNotFoundException nnfe) {
8887                return -1;
8888            }
8889        }
8890    }
8891
8892    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8893        @Override
8894        public int checkComponentPermission(String permission, int pid, int uid,
8895                int owningUid, boolean exported) {
8896            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8897                    owningUid, exported);
8898        }
8899
8900        @Override
8901        public Object getAMSLock() {
8902            return ActivityManagerService.this;
8903        }
8904    }
8905
8906    int checkComponentPermission(String permission, int pid, int uid,
8907            int owningUid, boolean exported) {
8908        if (pid == MY_PID) {
8909            return PackageManager.PERMISSION_GRANTED;
8910        }
8911        return ActivityManager.checkComponentPermission(permission, uid,
8912                owningUid, exported);
8913    }
8914
8915    /**
8916     * As the only public entry point for permissions checking, this method
8917     * can enforce the semantic that requesting a check on a null global
8918     * permission is automatically denied.  (Internally a null permission
8919     * string is used when calling {@link #checkComponentPermission} in cases
8920     * when only uid-based security is needed.)
8921     *
8922     * This can be called with or without the global lock held.
8923     */
8924    @Override
8925    public int checkPermission(String permission, int pid, int uid) {
8926        if (permission == null) {
8927            return PackageManager.PERMISSION_DENIED;
8928        }
8929        return checkComponentPermission(permission, pid, uid, -1, true);
8930    }
8931
8932    @Override
8933    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8934        if (permission == null) {
8935            return PackageManager.PERMISSION_DENIED;
8936        }
8937
8938        // We might be performing an operation on behalf of an indirect binder
8939        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8940        // client identity accordingly before proceeding.
8941        Identity tlsIdentity = sCallerIdentity.get();
8942        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8943            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8944                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8945            uid = tlsIdentity.uid;
8946            pid = tlsIdentity.pid;
8947        }
8948
8949        return checkComponentPermission(permission, pid, uid, -1, true);
8950    }
8951
8952    /**
8953     * Binder IPC calls go through the public entry point.
8954     * This can be called with or without the global lock held.
8955     */
8956    int checkCallingPermission(String permission) {
8957        return checkPermission(permission,
8958                Binder.getCallingPid(),
8959                UserHandle.getAppId(Binder.getCallingUid()));
8960    }
8961
8962    /**
8963     * This can be called with or without the global lock held.
8964     */
8965    void enforceCallingPermission(String permission, String func) {
8966        if (checkCallingPermission(permission)
8967                == PackageManager.PERMISSION_GRANTED) {
8968            return;
8969        }
8970
8971        String msg = "Permission Denial: " + func + " from pid="
8972                + Binder.getCallingPid()
8973                + ", uid=" + Binder.getCallingUid()
8974                + " requires " + permission;
8975        Slog.w(TAG, msg);
8976        throw new SecurityException(msg);
8977    }
8978
8979    /**
8980     * This can be called with or without the global lock held.
8981     */
8982    void enforcePermission(String permission, int pid, int uid, String func) {
8983        if (checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED) {
8984            return;
8985        }
8986
8987        String msg = "Permission Denial: " + func + " from pid=" + pid + ", uid=" + uid
8988                + " requires " + permission;
8989        Slog.w(TAG, msg);
8990        throw new SecurityException(msg);
8991    }
8992
8993    /**
8994     * This can be called with or without the global lock held.
8995     */
8996    void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
8997        if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
8998            enforceCallingPermission(permission, func);
8999        }
9000    }
9001
9002    /**
9003     * Determine if UID is holding permissions required to access {@link Uri} in
9004     * the given {@link ProviderInfo}. Final permission checking is always done
9005     * in {@link ContentProvider}.
9006     */
9007    private final boolean checkHoldingPermissionsLocked(
9008            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
9009        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9010                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
9011        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
9012            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
9013                    != PERMISSION_GRANTED) {
9014                return false;
9015            }
9016        }
9017        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
9018    }
9019
9020    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
9021            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
9022        if (pi.applicationInfo.uid == uid) {
9023            return true;
9024        } else if (!pi.exported) {
9025            return false;
9026        }
9027
9028        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
9029        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
9030        try {
9031            // check if target holds top-level <provider> permissions
9032            if (!readMet && pi.readPermission != null && considerUidPermissions
9033                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
9034                readMet = true;
9035            }
9036            if (!writeMet && pi.writePermission != null && considerUidPermissions
9037                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
9038                writeMet = true;
9039            }
9040
9041            // track if unprotected read/write is allowed; any denied
9042            // <path-permission> below removes this ability
9043            boolean allowDefaultRead = pi.readPermission == null;
9044            boolean allowDefaultWrite = pi.writePermission == null;
9045
9046            // check if target holds any <path-permission> that match uri
9047            final PathPermission[] pps = pi.pathPermissions;
9048            if (pps != null) {
9049                final String path = grantUri.uri.getPath();
9050                int i = pps.length;
9051                while (i > 0 && (!readMet || !writeMet)) {
9052                    i--;
9053                    PathPermission pp = pps[i];
9054                    if (pp.match(path)) {
9055                        if (!readMet) {
9056                            final String pprperm = pp.getReadPermission();
9057                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9058                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
9059                                    + ": match=" + pp.match(path)
9060                                    + " check=" + pm.checkUidPermission(pprperm, uid));
9061                            if (pprperm != null) {
9062                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
9063                                        == PERMISSION_GRANTED) {
9064                                    readMet = true;
9065                                } else {
9066                                    allowDefaultRead = false;
9067                                }
9068                            }
9069                        }
9070                        if (!writeMet) {
9071                            final String ppwperm = pp.getWritePermission();
9072                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9073                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
9074                                    + ": match=" + pp.match(path)
9075                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
9076                            if (ppwperm != null) {
9077                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
9078                                        == PERMISSION_GRANTED) {
9079                                    writeMet = true;
9080                                } else {
9081                                    allowDefaultWrite = false;
9082                                }
9083                            }
9084                        }
9085                    }
9086                }
9087            }
9088
9089            // grant unprotected <provider> read/write, if not blocked by
9090            // <path-permission> above
9091            if (allowDefaultRead) readMet = true;
9092            if (allowDefaultWrite) writeMet = true;
9093
9094        } catch (RemoteException e) {
9095            return false;
9096        }
9097
9098        return readMet && writeMet;
9099    }
9100
9101    public boolean isAppStartModeDisabled(int uid, String packageName) {
9102        synchronized (this) {
9103            return getAppStartModeLocked(uid, packageName, 0, -1, false, true, false)
9104                    == ActivityManager.APP_START_MODE_DISABLED;
9105        }
9106    }
9107
9108    // Unified app-op and target sdk check
9109    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9110        // Apps that target O+ are always subject to background check
9111        if (packageTargetSdk >= Build.VERSION_CODES.O) {
9112            if (DEBUG_BACKGROUND_CHECK) {
9113                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
9114            }
9115            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9116        }
9117        // ...and legacy apps get an AppOp check
9118        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
9119                uid, packageName);
9120        if (DEBUG_BACKGROUND_CHECK) {
9121            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
9122        }
9123        switch (appop) {
9124            case AppOpsManager.MODE_ALLOWED:
9125                // If force-background-check is enabled, restrict all apps that aren't whitelisted.
9126                if (mForceBackgroundCheck &&
9127                        !UserHandle.isCore(uid) &&
9128                        !isOnDeviceIdleWhitelistLocked(uid)) {
9129                    if (DEBUG_BACKGROUND_CHECK) {
9130                        Slog.i(TAG, "Force background check: " +
9131                                uid + "/" + packageName + " restricted");
9132                    }
9133                    return ActivityManager.APP_START_MODE_DELAYED;
9134                }
9135                return ActivityManager.APP_START_MODE_NORMAL;
9136            case AppOpsManager.MODE_IGNORED:
9137                return ActivityManager.APP_START_MODE_DELAYED;
9138            default:
9139                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9140        }
9141    }
9142
9143    // Service launch is available to apps with run-in-background exemptions but
9144    // some other background operations are not.  If we're doing a check
9145    // of service-launch policy, allow those callers to proceed unrestricted.
9146    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9147        // Persistent app?
9148        if (mPackageManagerInt.isPackagePersistent(packageName)) {
9149            if (DEBUG_BACKGROUND_CHECK) {
9150                Slog.i(TAG, "App " + uid + "/" + packageName
9151                        + " is persistent; not restricted in background");
9152            }
9153            return ActivityManager.APP_START_MODE_NORMAL;
9154        }
9155
9156        // Non-persistent but background whitelisted?
9157        if (uidOnBackgroundWhitelist(uid)) {
9158            if (DEBUG_BACKGROUND_CHECK) {
9159                Slog.i(TAG, "App " + uid + "/" + packageName
9160                        + " on background whitelist; not restricted in background");
9161            }
9162            return ActivityManager.APP_START_MODE_NORMAL;
9163        }
9164
9165        // Is this app on the battery whitelist?
9166        if (isOnDeviceIdleWhitelistLocked(uid)) {
9167            if (DEBUG_BACKGROUND_CHECK) {
9168                Slog.i(TAG, "App " + uid + "/" + packageName
9169                        + " on idle whitelist; not restricted in background");
9170            }
9171            return ActivityManager.APP_START_MODE_NORMAL;
9172        }
9173
9174        // None of the service-policy criteria apply, so we apply the common criteria
9175        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
9176    }
9177
9178    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
9179            int callingPid, boolean alwaysRestrict, boolean disabledOnly, boolean forcedStandby) {
9180        UidRecord uidRec = mActiveUids.get(uid);
9181        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
9182                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
9183                + (uidRec != null ? uidRec.idle : false));
9184        if (uidRec == null || alwaysRestrict || forcedStandby || uidRec.idle) {
9185            boolean ephemeral;
9186            if (uidRec == null) {
9187                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
9188                        UserHandle.getUserId(uid), packageName);
9189            } else {
9190                ephemeral = uidRec.ephemeral;
9191            }
9192
9193            if (ephemeral) {
9194                // We are hard-core about ephemeral apps not running in the background.
9195                return ActivityManager.APP_START_MODE_DISABLED;
9196            } else {
9197                if (disabledOnly) {
9198                    // The caller is only interested in whether app starts are completely
9199                    // disabled for the given package (that is, it is an instant app).  So
9200                    // we don't need to go further, which is all just seeing if we should
9201                    // apply a "delayed" mode for a regular app.
9202                    return ActivityManager.APP_START_MODE_NORMAL;
9203                }
9204                final int startMode = (alwaysRestrict)
9205                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
9206                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
9207                                packageTargetSdk);
9208                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
9209                        + " pkg=" + packageName + " startMode=" + startMode
9210                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
9211                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
9212                    // This is an old app that has been forced into a "compatible as possible"
9213                    // mode of background check.  To increase compatibility, we will allow other
9214                    // foreground apps to cause its services to start.
9215                    if (callingPid >= 0) {
9216                        ProcessRecord proc;
9217                        synchronized (mPidsSelfLocked) {
9218                            proc = mPidsSelfLocked.get(callingPid);
9219                        }
9220                        if (proc != null &&
9221                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
9222                            // Whoever is instigating this is in the foreground, so we will allow it
9223                            // to go through.
9224                            return ActivityManager.APP_START_MODE_NORMAL;
9225                        }
9226                    }
9227                }
9228                return startMode;
9229            }
9230        }
9231        return ActivityManager.APP_START_MODE_NORMAL;
9232    }
9233
9234    /**
9235     * @return whether a UID is in the system, user or temp doze whitelist.
9236     */
9237    boolean isOnDeviceIdleWhitelistLocked(int uid) {
9238        final int appId = UserHandle.getAppId(uid);
9239        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
9240                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
9241                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
9242    }
9243
9244    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
9245        ProviderInfo pi = null;
9246        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
9247        if (cpr != null) {
9248            pi = cpr.info;
9249        } else {
9250            try {
9251                pi = AppGlobals.getPackageManager().resolveContentProvider(
9252                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
9253                        userHandle);
9254            } catch (RemoteException ex) {
9255            }
9256        }
9257        return pi;
9258    }
9259
9260    void grantEphemeralAccessLocked(int userId, Intent intent,
9261            int targetAppId, int ephemeralAppId) {
9262        getPackageManagerInternalLocked().
9263                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
9264    }
9265
9266    @GuardedBy("this")
9267    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
9268        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9269        if (targetUris != null) {
9270            return targetUris.get(grantUri);
9271        }
9272        return null;
9273    }
9274
9275    @GuardedBy("this")
9276    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
9277            String targetPkg, int targetUid, GrantUri grantUri) {
9278        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9279        if (targetUris == null) {
9280            targetUris = Maps.newArrayMap();
9281            mGrantedUriPermissions.put(targetUid, targetUris);
9282        }
9283
9284        UriPermission perm = targetUris.get(grantUri);
9285        if (perm == null) {
9286            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
9287            targetUris.put(grantUri, perm);
9288        }
9289
9290        return perm;
9291    }
9292
9293    @GuardedBy("this")
9294    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
9295            final int modeFlags) {
9296        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
9297        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
9298                : UriPermission.STRENGTH_OWNED;
9299
9300        // Root gets to do everything.
9301        if (uid == 0) {
9302            return true;
9303        }
9304
9305        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9306        if (perms == null) return false;
9307
9308        // First look for exact match
9309        final UriPermission exactPerm = perms.get(grantUri);
9310        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
9311            return true;
9312        }
9313
9314        // No exact match, look for prefixes
9315        final int N = perms.size();
9316        for (int i = 0; i < N; i++) {
9317            final UriPermission perm = perms.valueAt(i);
9318            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
9319                    && perm.getStrength(modeFlags) >= minStrength) {
9320                return true;
9321            }
9322        }
9323
9324        return false;
9325    }
9326
9327    /**
9328     * @param uri This uri must NOT contain an embedded userId.
9329     * @param userId The userId in which the uri is to be resolved.
9330     */
9331    @Override
9332    public int checkUriPermission(Uri uri, int pid, int uid,
9333            final int modeFlags, int userId, IBinder callerToken) {
9334        enforceNotIsolatedCaller("checkUriPermission");
9335
9336        // Another redirected-binder-call permissions check as in
9337        // {@link checkPermissionWithToken}.
9338        Identity tlsIdentity = sCallerIdentity.get();
9339        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9340            uid = tlsIdentity.uid;
9341            pid = tlsIdentity.pid;
9342        }
9343
9344        // Our own process gets to do everything.
9345        if (pid == MY_PID) {
9346            return PackageManager.PERMISSION_GRANTED;
9347        }
9348        synchronized (this) {
9349            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
9350                    ? PackageManager.PERMISSION_GRANTED
9351                    : PackageManager.PERMISSION_DENIED;
9352        }
9353    }
9354
9355    /**
9356     * Check if the targetPkg can be granted permission to access uri by
9357     * the callingUid using the given modeFlags.  Throws a security exception
9358     * if callingUid is not allowed to do this.  Returns the uid of the target
9359     * if the URI permission grant should be performed; returns -1 if it is not
9360     * needed (for example targetPkg already has permission to access the URI).
9361     * If you already know the uid of the target, you can supply it in
9362     * lastTargetUid else set that to -1.
9363     */
9364    @GuardedBy("this")
9365    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9366            final int modeFlags, int lastTargetUid) {
9367        if (!Intent.isAccessUriMode(modeFlags)) {
9368            return -1;
9369        }
9370
9371        if (targetPkg != null) {
9372            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9373                    "Checking grant " + targetPkg + " permission to " + grantUri);
9374        }
9375
9376        final IPackageManager pm = AppGlobals.getPackageManager();
9377
9378        // If this is not a content: uri, we can't do anything with it.
9379        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
9380            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9381                    "Can't grant URI permission for non-content URI: " + grantUri);
9382            return -1;
9383        }
9384
9385        // Bail early if system is trying to hand out permissions directly; it
9386        // must always grant permissions on behalf of someone explicit.
9387        final int callingAppId = UserHandle.getAppId(callingUid);
9388        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
9389            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
9390                // Exempted authority for
9391                // 1. cropping user photos and sharing a generated license html
9392                //    file in Settings app
9393                // 2. sharing a generated license html file in TvSettings app
9394            } else {
9395                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
9396                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
9397                return -1;
9398            }
9399        }
9400
9401        final String authority = grantUri.uri.getAuthority();
9402        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9403                MATCH_DEBUG_TRIAGED_MISSING);
9404        if (pi == null) {
9405            Slog.w(TAG, "No content provider found for permission check: " +
9406                    grantUri.uri.toSafeString());
9407            return -1;
9408        }
9409
9410        int targetUid = lastTargetUid;
9411        if (targetUid < 0 && targetPkg != null) {
9412            try {
9413                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9414                        UserHandle.getUserId(callingUid));
9415                if (targetUid < 0) {
9416                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9417                            "Can't grant URI permission no uid for: " + targetPkg);
9418                    return -1;
9419                }
9420            } catch (RemoteException ex) {
9421                return -1;
9422            }
9423        }
9424
9425        // If we're extending a persistable grant, then we always need to create
9426        // the grant data structure so that take/release APIs work
9427        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
9428            return targetUid;
9429        }
9430
9431        if (targetUid >= 0) {
9432            // First...  does the target actually need this permission?
9433            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
9434                // No need to grant the target this permission.
9435                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9436                        "Target " + targetPkg + " already has full permission to " + grantUri);
9437                return -1;
9438            }
9439        } else {
9440            // First...  there is no target package, so can anyone access it?
9441            boolean allowed = pi.exported;
9442            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9443                if (pi.readPermission != null) {
9444                    allowed = false;
9445                }
9446            }
9447            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9448                if (pi.writePermission != null) {
9449                    allowed = false;
9450                }
9451            }
9452            if (pi.pathPermissions != null) {
9453                final int N = pi.pathPermissions.length;
9454                for (int i=0; i<N; i++) {
9455                    if (pi.pathPermissions[i] != null
9456                            && pi.pathPermissions[i].match(grantUri.uri.getPath())) {
9457                        if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9458                            if (pi.pathPermissions[i].getReadPermission() != null) {
9459                                allowed = false;
9460                            }
9461                        }
9462                        if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9463                            if (pi.pathPermissions[i].getWritePermission() != null) {
9464                                allowed = false;
9465                            }
9466                        }
9467                        break;
9468                    }
9469                }
9470            }
9471            if (allowed) {
9472                return -1;
9473            }
9474        }
9475
9476        /* There is a special cross user grant if:
9477         * - The target is on another user.
9478         * - Apps on the current user can access the uri without any uid permissions.
9479         * In this case, we grant a uri permission, even if the ContentProvider does not normally
9480         * grant uri permissions.
9481         */
9482        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
9483                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
9484                modeFlags, false /*without considering the uid permissions*/);
9485
9486        // Second...  is the provider allowing granting of URI permissions?
9487        if (!specialCrossUserGrant) {
9488            if (!pi.grantUriPermissions) {
9489                throw new SecurityException("Provider " + pi.packageName
9490                        + "/" + pi.name
9491                        + " does not allow granting of Uri permissions (uri "
9492                        + grantUri + ")");
9493            }
9494            if (pi.uriPermissionPatterns != null) {
9495                final int N = pi.uriPermissionPatterns.length;
9496                boolean allowed = false;
9497                for (int i=0; i<N; i++) {
9498                    if (pi.uriPermissionPatterns[i] != null
9499                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
9500                        allowed = true;
9501                        break;
9502                    }
9503                }
9504                if (!allowed) {
9505                    throw new SecurityException("Provider " + pi.packageName
9506                            + "/" + pi.name
9507                            + " does not allow granting of permission to path of Uri "
9508                            + grantUri);
9509                }
9510            }
9511        }
9512
9513        // Third...  does the caller itself have permission to access
9514        // this uri?
9515        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9516            // Require they hold a strong enough Uri permission
9517            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
9518                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
9519                    throw new SecurityException(
9520                            "UID " + callingUid + " does not have permission to " + grantUri
9521                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
9522                                    + "or related APIs");
9523                } else {
9524                    throw new SecurityException(
9525                            "UID " + callingUid + " does not have permission to " + grantUri);
9526                }
9527            }
9528        }
9529        return targetUid;
9530    }
9531
9532    /**
9533     * @param uri This uri must NOT contain an embedded userId.
9534     * @param userId The userId in which the uri is to be resolved.
9535     */
9536    @Override
9537    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
9538            final int modeFlags, int userId) {
9539        enforceNotIsolatedCaller("checkGrantUriPermission");
9540        synchronized(this) {
9541            return checkGrantUriPermissionLocked(callingUid, targetPkg,
9542                    new GrantUri(userId, uri, false), modeFlags, -1);
9543        }
9544    }
9545
9546    @GuardedBy("this")
9547    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
9548            final int modeFlags, UriPermissionOwner owner) {
9549        if (!Intent.isAccessUriMode(modeFlags)) {
9550            return;
9551        }
9552
9553        // So here we are: the caller has the assumed permission
9554        // to the uri, and the target doesn't.  Let's now give this to
9555        // the target.
9556
9557        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9558                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
9559
9560        final String authority = grantUri.uri.getAuthority();
9561        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9562                MATCH_DEBUG_TRIAGED_MISSING);
9563        if (pi == null) {
9564            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
9565            return;
9566        }
9567
9568        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
9569            grantUri.prefix = true;
9570        }
9571        final UriPermission perm = findOrCreateUriPermissionLocked(
9572                pi.packageName, targetPkg, targetUid, grantUri);
9573        perm.grantModes(modeFlags, owner);
9574    }
9575
9576    @GuardedBy("this")
9577    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9578            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9579        if (targetPkg == null) {
9580            throw new NullPointerException("targetPkg");
9581        }
9582        int targetUid;
9583        final IPackageManager pm = AppGlobals.getPackageManager();
9584        try {
9585            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9586        } catch (RemoteException ex) {
9587            return;
9588        }
9589
9590        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9591                targetUid);
9592        if (targetUid < 0) {
9593            return;
9594        }
9595
9596        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9597                owner);
9598    }
9599
9600    static class NeededUriGrants extends ArrayList<GrantUri> {
9601        final String targetPkg;
9602        final int targetUid;
9603        final int flags;
9604
9605        NeededUriGrants(String targetPkg, int targetUid, int flags) {
9606            this.targetPkg = targetPkg;
9607            this.targetUid = targetUid;
9608            this.flags = flags;
9609        }
9610
9611        void writeToProto(ProtoOutputStream proto, long fieldId) {
9612            long token = proto.start(fieldId);
9613            proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
9614            proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
9615            proto.write(NeededUriGrantsProto.FLAGS, flags);
9616
9617            final int N = this.size();
9618            for (int i=0; i<N; i++) {
9619                this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
9620            }
9621            proto.end(token);
9622        }
9623    }
9624
9625    /**
9626     * Like checkGrantUriPermissionLocked, but takes an Intent.
9627     */
9628    @GuardedBy("this")
9629    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9630            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9631        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9632                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9633                + " clip=" + (intent != null ? intent.getClipData() : null)
9634                + " from " + intent + "; flags=0x"
9635                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9636
9637        if (targetPkg == null) {
9638            throw new NullPointerException("targetPkg");
9639        }
9640
9641        if (intent == null) {
9642            return null;
9643        }
9644        Uri data = intent.getData();
9645        ClipData clip = intent.getClipData();
9646        if (data == null && clip == null) {
9647            return null;
9648        }
9649        // Default userId for uris in the intent (if they don't specify it themselves)
9650        int contentUserHint = intent.getContentUserHint();
9651        if (contentUserHint == UserHandle.USER_CURRENT) {
9652            contentUserHint = UserHandle.getUserId(callingUid);
9653        }
9654        final IPackageManager pm = AppGlobals.getPackageManager();
9655        int targetUid;
9656        if (needed != null) {
9657            targetUid = needed.targetUid;
9658        } else {
9659            try {
9660                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9661                        targetUserId);
9662            } catch (RemoteException ex) {
9663                return null;
9664            }
9665            if (targetUid < 0) {
9666                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9667                        "Can't grant URI permission no uid for: " + targetPkg
9668                        + " on user " + targetUserId);
9669                return null;
9670            }
9671        }
9672        if (data != null) {
9673            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9674            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9675                    targetUid);
9676            if (targetUid > 0) {
9677                if (needed == null) {
9678                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
9679                }
9680                needed.add(grantUri);
9681            }
9682        }
9683        if (clip != null) {
9684            for (int i=0; i<clip.getItemCount(); i++) {
9685                Uri uri = clip.getItemAt(i).getUri();
9686                if (uri != null) {
9687                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9688                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9689                            targetUid);
9690                    if (targetUid > 0) {
9691                        if (needed == null) {
9692                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
9693                        }
9694                        needed.add(grantUri);
9695                    }
9696                } else {
9697                    Intent clipIntent = clip.getItemAt(i).getIntent();
9698                    if (clipIntent != null) {
9699                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9700                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9701                        if (newNeeded != null) {
9702                            needed = newNeeded;
9703                        }
9704                    }
9705                }
9706            }
9707        }
9708
9709        return needed;
9710    }
9711
9712    /**
9713     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9714     */
9715    @GuardedBy("this")
9716    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9717            UriPermissionOwner owner) {
9718        if (needed != null) {
9719            for (int i=0; i<needed.size(); i++) {
9720                GrantUri grantUri = needed.get(i);
9721                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9722                        grantUri, needed.flags, owner);
9723            }
9724        }
9725    }
9726
9727    @GuardedBy("this")
9728    void grantUriPermissionFromIntentLocked(int callingUid,
9729            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9730        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9731                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9732        if (needed == null) {
9733            return;
9734        }
9735
9736        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9737    }
9738
9739    /**
9740     * @param uri This uri must NOT contain an embedded userId.
9741     * @param userId The userId in which the uri is to be resolved.
9742     */
9743    @Override
9744    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9745            final int modeFlags, int userId) {
9746        enforceNotIsolatedCaller("grantUriPermission");
9747        GrantUri grantUri = new GrantUri(userId, uri, false);
9748        synchronized(this) {
9749            final ProcessRecord r = getRecordForAppLocked(caller);
9750            if (r == null) {
9751                throw new SecurityException("Unable to find app for caller "
9752                        + caller
9753                        + " when granting permission to uri " + grantUri);
9754            }
9755            if (targetPkg == null) {
9756                throw new IllegalArgumentException("null target");
9757            }
9758            if (grantUri == null) {
9759                throw new IllegalArgumentException("null uri");
9760            }
9761
9762            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9763                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9764                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9765                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9766
9767            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9768                    UserHandle.getUserId(r.uid));
9769        }
9770    }
9771
9772    @GuardedBy("this")
9773    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9774        if (perm.modeFlags == 0) {
9775            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9776                    perm.targetUid);
9777            if (perms != null) {
9778                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9779                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9780
9781                perms.remove(perm.uri);
9782                if (perms.isEmpty()) {
9783                    mGrantedUriPermissions.remove(perm.targetUid);
9784                }
9785            }
9786        }
9787    }
9788
9789    @GuardedBy("this")
9790    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9791            final int modeFlags) {
9792        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9793                "Revoking all granted permissions to " + grantUri);
9794
9795        final IPackageManager pm = AppGlobals.getPackageManager();
9796        final String authority = grantUri.uri.getAuthority();
9797        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9798                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9799        if (pi == null) {
9800            Slog.w(TAG, "No content provider found for permission revoke: "
9801                    + grantUri.toSafeString());
9802            return;
9803        }
9804
9805        // Does the caller have this permission on the URI?
9806        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9807            // If they don't have direct access to the URI, then revoke any
9808            // ownerless URI permissions that have been granted to them.
9809            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9810            if (perms != null) {
9811                boolean persistChanged = false;
9812                for (int i = perms.size()-1; i >= 0; i--) {
9813                    final UriPermission perm = perms.valueAt(i);
9814                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9815                        continue;
9816                    }
9817                    if (perm.uri.sourceUserId == grantUri.sourceUserId
9818                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9819                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9820                                "Revoking non-owned " + perm.targetUid
9821                                + " permission to " + perm.uri);
9822                        persistChanged |= perm.revokeModes(
9823                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9824                        if (perm.modeFlags == 0) {
9825                            perms.removeAt(i);
9826                        }
9827                    }
9828                }
9829                if (perms.isEmpty()) {
9830                    mGrantedUriPermissions.remove(callingUid);
9831                }
9832                if (persistChanged) {
9833                    schedulePersistUriGrants();
9834                }
9835            }
9836            return;
9837        }
9838
9839        boolean persistChanged = false;
9840
9841        // Go through all of the permissions and remove any that match.
9842        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9843            final int targetUid = mGrantedUriPermissions.keyAt(i);
9844            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9845
9846            for (int j = perms.size()-1; j >= 0; j--) {
9847                final UriPermission perm = perms.valueAt(j);
9848                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9849                    continue;
9850                }
9851                if (perm.uri.sourceUserId == grantUri.sourceUserId
9852                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9853                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9854                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9855                    persistChanged |= perm.revokeModes(
9856                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9857                            targetPackage == null);
9858                    if (perm.modeFlags == 0) {
9859                        perms.removeAt(j);
9860                    }
9861                }
9862            }
9863
9864            if (perms.isEmpty()) {
9865                mGrantedUriPermissions.removeAt(i);
9866            }
9867        }
9868
9869        if (persistChanged) {
9870            schedulePersistUriGrants();
9871        }
9872    }
9873
9874    /**
9875     * @param uri This uri must NOT contain an embedded userId.
9876     * @param userId The userId in which the uri is to be resolved.
9877     */
9878    @Override
9879    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9880            final int modeFlags, int userId) {
9881        enforceNotIsolatedCaller("revokeUriPermission");
9882        synchronized(this) {
9883            final ProcessRecord r = getRecordForAppLocked(caller);
9884            if (r == null) {
9885                throw new SecurityException("Unable to find app for caller "
9886                        + caller
9887                        + " when revoking permission to uri " + uri);
9888            }
9889            if (uri == null) {
9890                Slog.w(TAG, "revokeUriPermission: null uri");
9891                return;
9892            }
9893
9894            if (!Intent.isAccessUriMode(modeFlags)) {
9895                return;
9896            }
9897
9898            final String authority = uri.getAuthority();
9899            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9900                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9901            if (pi == null) {
9902                Slog.w(TAG, "No content provider found for permission revoke: "
9903                        + uri.toSafeString());
9904                return;
9905            }
9906
9907            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9908                    modeFlags);
9909        }
9910    }
9911
9912    /**
9913     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9914     * given package.
9915     *
9916     * @param packageName Package name to match, or {@code null} to apply to all
9917     *            packages.
9918     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9919     *            to all users.
9920     * @param persistable If persistable grants should be removed.
9921     * @param targetOnly When {@code true}, only remove permissions where the app is the target,
9922     * not source.
9923     */
9924    @GuardedBy("this")
9925    private void removeUriPermissionsForPackageLocked(
9926            String packageName, int userHandle, boolean persistable, boolean targetOnly) {
9927        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9928            throw new IllegalArgumentException("Must narrow by either package or user");
9929        }
9930
9931        boolean persistChanged = false;
9932
9933        int N = mGrantedUriPermissions.size();
9934        for (int i = 0; i < N; i++) {
9935            final int targetUid = mGrantedUriPermissions.keyAt(i);
9936            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9937
9938            // Only inspect grants matching user
9939            if (userHandle == UserHandle.USER_ALL
9940                    || userHandle == UserHandle.getUserId(targetUid)) {
9941                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9942                    final UriPermission perm = it.next();
9943
9944                    // Only inspect grants matching package
9945                    if (packageName == null || (!targetOnly && perm.sourcePkg.equals(packageName))
9946                            || perm.targetPkg.equals(packageName)) {
9947                        // Hacky solution as part of fixing a security bug; ignore
9948                        // grants associated with DownloadManager so we don't have
9949                        // to immediately launch it to regrant the permissions
9950                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9951                                && !persistable) continue;
9952
9953                        persistChanged |= perm.revokeModes(persistable
9954                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9955
9956                        // Only remove when no modes remain; any persisted grants
9957                        // will keep this alive.
9958                        if (perm.modeFlags == 0) {
9959                            it.remove();
9960                        }
9961                    }
9962                }
9963
9964                if (perms.isEmpty()) {
9965                    mGrantedUriPermissions.remove(targetUid);
9966                    N--;
9967                    i--;
9968                }
9969            }
9970        }
9971
9972        if (persistChanged) {
9973            schedulePersistUriGrants();
9974        }
9975    }
9976
9977    @Override
9978    public IBinder newUriPermissionOwner(String name) {
9979        enforceNotIsolatedCaller("newUriPermissionOwner");
9980        synchronized(this) {
9981            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9982            return owner.getExternalTokenLocked();
9983        }
9984    }
9985
9986    @Override
9987    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9988        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9989        synchronized(this) {
9990            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9991            if (r == null) {
9992                throw new IllegalArgumentException("Activity does not exist; token="
9993                        + activityToken);
9994            }
9995            return r.getUriPermissionsLocked().getExternalTokenLocked();
9996        }
9997    }
9998    /**
9999     * @param uri This uri must NOT contain an embedded userId.
10000     * @param sourceUserId The userId in which the uri is to be resolved.
10001     * @param targetUserId The userId of the app that receives the grant.
10002     */
10003    @Override
10004    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
10005            final int modeFlags, int sourceUserId, int targetUserId) {
10006        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
10007                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
10008                "grantUriPermissionFromOwner", null);
10009        synchronized(this) {
10010            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
10011            if (owner == null) {
10012                throw new IllegalArgumentException("Unknown owner: " + token);
10013            }
10014            if (fromUid != Binder.getCallingUid()) {
10015                if (Binder.getCallingUid() != myUid()) {
10016                    // Only system code can grant URI permissions on behalf
10017                    // of other users.
10018                    throw new SecurityException("nice try");
10019                }
10020            }
10021            if (targetPkg == null) {
10022                throw new IllegalArgumentException("null target");
10023            }
10024            if (uri == null) {
10025                throw new IllegalArgumentException("null uri");
10026            }
10027
10028            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
10029                    modeFlags, owner, targetUserId);
10030        }
10031    }
10032
10033    /**
10034     * @param uri This uri must NOT contain an embedded userId.
10035     * @param userId The userId in which the uri is to be resolved.
10036     */
10037    @Override
10038    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
10039        synchronized(this) {
10040            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
10041            if (owner == null) {
10042                throw new IllegalArgumentException("Unknown owner: " + token);
10043            }
10044
10045            if (uri == null) {
10046                owner.removeUriPermissionsLocked(mode);
10047            } else {
10048                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
10049                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
10050            }
10051        }
10052    }
10053
10054    private void schedulePersistUriGrants() {
10055        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
10056            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
10057                    10 * DateUtils.SECOND_IN_MILLIS);
10058        }
10059    }
10060
10061    private void writeGrantedUriPermissions() {
10062        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
10063
10064        final long startTime = SystemClock.uptimeMillis();
10065
10066        // Snapshot permissions so we can persist without lock
10067        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
10068        synchronized (this) {
10069            final int size = mGrantedUriPermissions.size();
10070            for (int i = 0; i < size; i++) {
10071                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10072                for (UriPermission perm : perms.values()) {
10073                    if (perm.persistedModeFlags != 0) {
10074                        persist.add(perm.snapshot());
10075                    }
10076                }
10077            }
10078        }
10079
10080        FileOutputStream fos = null;
10081        try {
10082            fos = mGrantFile.startWrite(startTime);
10083
10084            XmlSerializer out = new FastXmlSerializer();
10085            out.setOutput(fos, StandardCharsets.UTF_8.name());
10086            out.startDocument(null, true);
10087            out.startTag(null, TAG_URI_GRANTS);
10088            for (UriPermission.Snapshot perm : persist) {
10089                out.startTag(null, TAG_URI_GRANT);
10090                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
10091                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
10092                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
10093                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
10094                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
10095                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
10096                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
10097                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
10098                out.endTag(null, TAG_URI_GRANT);
10099            }
10100            out.endTag(null, TAG_URI_GRANTS);
10101            out.endDocument();
10102
10103            mGrantFile.finishWrite(fos);
10104        } catch (IOException e) {
10105            if (fos != null) {
10106                mGrantFile.failWrite(fos);
10107            }
10108        }
10109    }
10110
10111    @GuardedBy("this")
10112    private void readGrantedUriPermissionsLocked() {
10113        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
10114
10115        final long now = System.currentTimeMillis();
10116
10117        FileInputStream fis = null;
10118        try {
10119            fis = mGrantFile.openRead();
10120            final XmlPullParser in = Xml.newPullParser();
10121            in.setInput(fis, StandardCharsets.UTF_8.name());
10122
10123            int type;
10124            while ((type = in.next()) != END_DOCUMENT) {
10125                final String tag = in.getName();
10126                if (type == START_TAG) {
10127                    if (TAG_URI_GRANT.equals(tag)) {
10128                        final int sourceUserId;
10129                        final int targetUserId;
10130                        final int userHandle = readIntAttribute(in,
10131                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
10132                        if (userHandle != UserHandle.USER_NULL) {
10133                            // For backwards compatibility.
10134                            sourceUserId = userHandle;
10135                            targetUserId = userHandle;
10136                        } else {
10137                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
10138                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
10139                        }
10140                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
10141                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
10142                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
10143                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
10144                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
10145                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
10146
10147                        // Sanity check that provider still belongs to source package
10148                        // Both direct boot aware and unaware packages are fine as we
10149                        // will do filtering at query time to avoid multiple parsing.
10150                        final ProviderInfo pi = getProviderInfoLocked(
10151                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
10152                                        | MATCH_DIRECT_BOOT_UNAWARE);
10153                        if (pi != null && sourcePkg.equals(pi.packageName)) {
10154                            int targetUid = -1;
10155                            try {
10156                                targetUid = AppGlobals.getPackageManager().getPackageUid(
10157                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
10158                            } catch (RemoteException e) {
10159                            }
10160                            if (targetUid != -1) {
10161                                final UriPermission perm = findOrCreateUriPermissionLocked(
10162                                        sourcePkg, targetPkg, targetUid,
10163                                        new GrantUri(sourceUserId, uri, prefix));
10164                                perm.initPersistedModes(modeFlags, createdTime);
10165                            }
10166                        } else {
10167                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
10168                                    + " but instead found " + pi);
10169                        }
10170                    }
10171                }
10172            }
10173        } catch (FileNotFoundException e) {
10174            // Missing grants is okay
10175        } catch (IOException e) {
10176            Slog.wtf(TAG, "Failed reading Uri grants", e);
10177        } catch (XmlPullParserException e) {
10178            Slog.wtf(TAG, "Failed reading Uri grants", e);
10179        } finally {
10180            IoUtils.closeQuietly(fis);
10181        }
10182    }
10183
10184    /**
10185     * @param uri This uri must NOT contain an embedded userId.
10186     * @param toPackage Name of package whose uri is being granted to (if {@code null}, uses
10187     * calling uid)
10188     * @param userId The userId in which the uri is to be resolved.
10189     */
10190    @Override
10191    public void takePersistableUriPermission(Uri uri, final int modeFlags,
10192            @Nullable String toPackage, int userId) {
10193        final int uid;
10194        if (toPackage != null) {
10195            enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10196                    "takePersistableUriPermission");
10197            uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10198        } else {
10199            enforceNotIsolatedCaller("takePersistableUriPermission");
10200            uid = Binder.getCallingUid();
10201        }
10202
10203        Preconditions.checkFlagsArgument(modeFlags,
10204                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10205
10206        synchronized (this) {
10207            boolean persistChanged = false;
10208            GrantUri grantUri = new GrantUri(userId, uri, false);
10209
10210            UriPermission exactPerm = findUriPermissionLocked(uid, grantUri);
10211            UriPermission prefixPerm = findUriPermissionLocked(uid,
10212                    new GrantUri(userId, uri, true));
10213
10214            final boolean exactValid = (exactPerm != null)
10215                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
10216            final boolean prefixValid = (prefixPerm != null)
10217                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
10218
10219            if (!(exactValid || prefixValid)) {
10220                throw new SecurityException("No persistable permission grants found for UID "
10221                        + uid + " and Uri " + grantUri.toSafeString());
10222            }
10223
10224            if (exactValid) {
10225                persistChanged |= exactPerm.takePersistableModes(modeFlags);
10226            }
10227            if (prefixValid) {
10228                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
10229            }
10230
10231            persistChanged |= maybePrunePersistedUriGrantsLocked(uid);
10232
10233            if (persistChanged) {
10234                schedulePersistUriGrants();
10235            }
10236        }
10237    }
10238
10239    /**
10240     * @param uri This uri must NOT contain an embedded userId.
10241     * @param toPackage Name of the target package whose uri is being released (if {@code null},
10242     * uses calling uid)
10243     * @param userId The userId in which the uri is to be resolved.
10244     */
10245    @Override
10246    public void releasePersistableUriPermission(Uri uri, final int modeFlags,
10247            @Nullable String toPackage, int userId) {
10248
10249        final int uid;
10250        if (toPackage != null) {
10251            enforceCallingPermission(android.Manifest.permission.FORCE_PERSISTABLE_URI_PERMISSIONS,
10252                    "releasePersistableUriPermission");
10253            uid = mPackageManagerInt.getPackageUid(toPackage, 0, userId);
10254        } else {
10255            enforceNotIsolatedCaller("releasePersistableUriPermission");
10256            uid = Binder.getCallingUid();
10257        }
10258
10259        Preconditions.checkFlagsArgument(modeFlags,
10260                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10261
10262        synchronized (this) {
10263            boolean persistChanged = false;
10264
10265            UriPermission exactPerm = findUriPermissionLocked(uid,
10266                    new GrantUri(userId, uri, false));
10267            UriPermission prefixPerm = findUriPermissionLocked(uid,
10268                    new GrantUri(userId, uri, true));
10269            if (exactPerm == null && prefixPerm == null && toPackage == null) {
10270                throw new SecurityException("No permission grants found for UID " + uid
10271                        + " and Uri " + uri.toSafeString());
10272            }
10273
10274            if (exactPerm != null) {
10275                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
10276                removeUriPermissionIfNeededLocked(exactPerm);
10277            }
10278            if (prefixPerm != null) {
10279                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
10280                removeUriPermissionIfNeededLocked(prefixPerm);
10281            }
10282
10283            if (persistChanged) {
10284                schedulePersistUriGrants();
10285            }
10286        }
10287    }
10288
10289    /**
10290     * Prune any older {@link UriPermission} for the given UID until outstanding
10291     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
10292     *
10293     * @return if any mutations occured that require persisting.
10294     */
10295    @GuardedBy("this")
10296    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
10297        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
10298        if (perms == null) return false;
10299        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
10300
10301        final ArrayList<UriPermission> persisted = Lists.newArrayList();
10302        for (UriPermission perm : perms.values()) {
10303            if (perm.persistedModeFlags != 0) {
10304                persisted.add(perm);
10305            }
10306        }
10307
10308        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
10309        if (trimCount <= 0) return false;
10310
10311        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
10312        for (int i = 0; i < trimCount; i++) {
10313            final UriPermission perm = persisted.get(i);
10314
10315            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10316                    "Trimming grant created at " + perm.persistedCreateTime);
10317
10318            perm.releasePersistableModes(~0);
10319            removeUriPermissionIfNeededLocked(perm);
10320        }
10321
10322        return true;
10323    }
10324
10325    @Override
10326    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
10327            String packageName, boolean incoming) {
10328        enforceNotIsolatedCaller("getPersistedUriPermissions");
10329        Preconditions.checkNotNull(packageName, "packageName");
10330
10331        final int callingUid = Binder.getCallingUid();
10332        final int callingUserId = UserHandle.getUserId(callingUid);
10333        final IPackageManager pm = AppGlobals.getPackageManager();
10334        try {
10335            final int packageUid = pm.getPackageUid(packageName,
10336                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
10337            if (packageUid != callingUid) {
10338                throw new SecurityException(
10339                        "Package " + packageName + " does not belong to calling UID " + callingUid);
10340            }
10341        } catch (RemoteException e) {
10342            throw new SecurityException("Failed to verify package name ownership");
10343        }
10344
10345        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10346        synchronized (this) {
10347            if (incoming) {
10348                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10349                        callingUid);
10350                if (perms == null) {
10351                    Slog.w(TAG, "No permission grants found for " + packageName);
10352                } else {
10353                    for (int j = 0; j < perms.size(); j++) {
10354                        final UriPermission perm = perms.valueAt(j);
10355                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
10356                            result.add(perm.buildPersistedPublicApiObject());
10357                        }
10358                    }
10359                }
10360            } else {
10361                final int size = mGrantedUriPermissions.size();
10362                for (int i = 0; i < size; i++) {
10363                    final ArrayMap<GrantUri, UriPermission> perms =
10364                            mGrantedUriPermissions.valueAt(i);
10365                    for (int j = 0; j < perms.size(); j++) {
10366                        final UriPermission perm = perms.valueAt(j);
10367                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
10368                            result.add(perm.buildPersistedPublicApiObject());
10369                        }
10370                    }
10371                }
10372            }
10373        }
10374        return new ParceledListSlice<android.content.UriPermission>(result);
10375    }
10376
10377    @Override
10378    public ParceledListSlice<GrantedUriPermission> getGrantedUriPermissions(
10379            @Nullable String packageName, int userId) {
10380        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10381                "getGrantedUriPermissions");
10382
10383        final List<GrantedUriPermission> result = new ArrayList<>();
10384        synchronized (this) {
10385            final int size = mGrantedUriPermissions.size();
10386            for (int i = 0; i < size; i++) {
10387                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10388                for (int j = 0; j < perms.size(); j++) {
10389                    final UriPermission perm = perms.valueAt(j);
10390                    if ((packageName == null || packageName.equals(perm.targetPkg))
10391                            && perm.targetUserId == userId
10392                            && perm.persistedModeFlags != 0) {
10393                        result.add(perm.buildGrantedUriPermission());
10394                    }
10395                }
10396            }
10397        }
10398        return new ParceledListSlice<>(result);
10399    }
10400
10401    @Override
10402    public void clearGrantedUriPermissions(String packageName, int userId) {
10403        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
10404                "clearGrantedUriPermissions");
10405        synchronized(this) {
10406            removeUriPermissionsForPackageLocked(packageName, userId, true, true);
10407        }
10408    }
10409
10410    @Override
10411    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
10412        synchronized (this) {
10413            ProcessRecord app =
10414                who != null ? getRecordForAppLocked(who) : null;
10415            if (app == null) return;
10416
10417            Message msg = Message.obtain();
10418            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
10419            msg.obj = app;
10420            msg.arg1 = waiting ? 1 : 0;
10421            mUiHandler.sendMessage(msg);
10422        }
10423    }
10424
10425    @Override
10426    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
10427        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
10428        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
10429        outInfo.availMem = getFreeMemory();
10430        outInfo.totalMem = getTotalMemory();
10431        outInfo.threshold = homeAppMem;
10432        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
10433        outInfo.hiddenAppThreshold = cachedAppMem;
10434        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
10435                ProcessList.SERVICE_ADJ);
10436        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
10437                ProcessList.VISIBLE_APP_ADJ);
10438        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
10439                ProcessList.FOREGROUND_APP_ADJ);
10440    }
10441
10442    // =========================================================
10443    // TASK MANAGEMENT
10444    // =========================================================
10445
10446    @Override
10447    public List<IBinder> getAppTasks(String callingPackage) {
10448        int callingUid = Binder.getCallingUid();
10449        long ident = Binder.clearCallingIdentity();
10450        try {
10451            synchronized(this) {
10452                return mRecentTasks.getAppTasksList(callingUid, callingPackage);
10453            }
10454        } finally {
10455            Binder.restoreCallingIdentity(ident);
10456        }
10457    }
10458
10459    @Override
10460    public List<RunningTaskInfo> getTasks(int maxNum) {
10461       return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
10462    }
10463
10464    @Override
10465    public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
10466            @WindowingMode int ignoreWindowingMode) {
10467        final int callingUid = Binder.getCallingUid();
10468        ArrayList<RunningTaskInfo> list = new ArrayList<>();
10469
10470        synchronized(this) {
10471            if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
10472
10473            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
10474                    callingUid);
10475            mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
10476                    ignoreWindowingMode, callingUid, allowed);
10477        }
10478
10479        return list;
10480    }
10481
10482    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
10483        if (mRecentTasks.isCallerRecents(callingUid)) {
10484            // Always allow the recents component to get tasks
10485            return true;
10486        }
10487
10488        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
10489                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
10490        if (!allowed) {
10491            if (checkPermission(android.Manifest.permission.GET_TASKS,
10492                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
10493                // Temporary compatibility: some existing apps on the system image may
10494                // still be requesting the old permission and not switched to the new
10495                // one; if so, we'll still allow them full access.  This means we need
10496                // to see if they are holding the old permission and are a system app.
10497                try {
10498                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
10499                        allowed = true;
10500                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10501                                + " is using old GET_TASKS but privileged; allowing");
10502                    }
10503                } catch (RemoteException e) {
10504                }
10505            }
10506        }
10507        if (!allowed) {
10508            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10509                    + " does not hold REAL_GET_TASKS; limiting output");
10510        }
10511        return allowed;
10512    }
10513
10514    @Override
10515    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
10516            int userId) {
10517        final int callingUid = Binder.getCallingUid();
10518        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
10519                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
10520        final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
10521                callingUid);
10522        final boolean detailed = checkCallingPermission(
10523                android.Manifest.permission.GET_DETAILED_TASKS)
10524                        == PackageManager.PERMISSION_GRANTED;
10525
10526        synchronized (this) {
10527            return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
10528                    callingUid);
10529        }
10530    }
10531
10532    @Override
10533    public ActivityManager.TaskDescription getTaskDescription(int id) {
10534        synchronized (this) {
10535            enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
10536            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10537                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10538            if (tr != null) {
10539                return tr.lastTaskDescription;
10540            }
10541        }
10542        return null;
10543    }
10544
10545    @Override
10546    public int addAppTask(IBinder activityToken, Intent intent,
10547            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10548        final int callingUid = Binder.getCallingUid();
10549        final long callingIdent = Binder.clearCallingIdentity();
10550
10551        try {
10552            synchronized (this) {
10553                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10554                if (r == null) {
10555                    throw new IllegalArgumentException("Activity does not exist; token="
10556                            + activityToken);
10557                }
10558                ComponentName comp = intent.getComponent();
10559                if (comp == null) {
10560                    throw new IllegalArgumentException("Intent " + intent
10561                            + " must specify explicit component");
10562                }
10563                if (thumbnail.getWidth() != mThumbnailWidth
10564                        || thumbnail.getHeight() != mThumbnailHeight) {
10565                    throw new IllegalArgumentException("Bad thumbnail size: got "
10566                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10567                            + mThumbnailWidth + "x" + mThumbnailHeight);
10568                }
10569                if (intent.getSelector() != null) {
10570                    intent.setSelector(null);
10571                }
10572                if (intent.getSourceBounds() != null) {
10573                    intent.setSourceBounds(null);
10574                }
10575                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10576                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10577                        // The caller has added this as an auto-remove task...  that makes no
10578                        // sense, so turn off auto-remove.
10579                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10580                    }
10581                }
10582                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10583                    mLastAddedTaskActivity = null;
10584                }
10585                ActivityInfo ainfo = mLastAddedTaskActivity;
10586                if (ainfo == null) {
10587                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10588                            comp, 0, UserHandle.getUserId(callingUid));
10589                    if (ainfo.applicationInfo.uid != callingUid) {
10590                        throw new SecurityException(
10591                                "Can't add task for another application: target uid="
10592                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10593                    }
10594                }
10595
10596                TaskRecord task = TaskRecord.create(this,
10597                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10598                        ainfo, intent, description);
10599                if (!mRecentTasks.addToBottom(task)) {
10600                    return INVALID_TASK_ID;
10601                }
10602                r.getStack().addTask(task, !ON_TOP, "addAppTask");
10603
10604                // TODO: Send the thumbnail to WM to store it.
10605
10606                return task.taskId;
10607            }
10608        } finally {
10609            Binder.restoreCallingIdentity(callingIdent);
10610        }
10611    }
10612
10613    @Override
10614    public Point getAppTaskThumbnailSize() {
10615        synchronized (this) {
10616            return new Point(mThumbnailWidth,  mThumbnailHeight);
10617        }
10618    }
10619
10620    @Override
10621    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10622        synchronized (this) {
10623            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10624            if (r != null) {
10625                r.setTaskDescription(td);
10626                final TaskRecord task = r.getTask();
10627                task.updateTaskDescription();
10628                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10629            }
10630        }
10631    }
10632
10633    @Override
10634    public void setTaskResizeable(int taskId, int resizeableMode) {
10635        synchronized (this) {
10636            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10637                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10638            if (task == null) {
10639                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10640                return;
10641            }
10642            task.setResizeMode(resizeableMode);
10643        }
10644    }
10645
10646    @Override
10647    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10648        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10649        long ident = Binder.clearCallingIdentity();
10650        try {
10651            synchronized (this) {
10652                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10653                if (task == null) {
10654                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10655                    return;
10656                }
10657                // Place the task in the right stack if it isn't there already based on
10658                // the requested bounds.
10659                // The stack transition logic is:
10660                // - a null bounds on a freeform task moves that task to fullscreen
10661                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10662                //   that task to freeform
10663                // - otherwise the task is not moved
10664                ActivityStack stack = task.getStack();
10665                if (!task.getWindowConfiguration().canResizeTask()) {
10666                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10667                }
10668                if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
10669                    stack = stack.getDisplay().getOrCreateStack(
10670                            WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10671                } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
10672                    stack = stack.getDisplay().getOrCreateStack(
10673                            WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
10674                }
10675
10676                // Reparent the task to the right stack if necessary
10677                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10678                if (stack != task.getStack()) {
10679                    // Defer resume until the task is resized below
10680                    task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10681                            DEFER_RESUME, "resizeTask");
10682                    preserveWindow = false;
10683                }
10684
10685                // After reparenting (which only resizes the task to the stack bounds), resize the
10686                // task to the actual bounds provided
10687                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10688            }
10689        } finally {
10690            Binder.restoreCallingIdentity(ident);
10691        }
10692    }
10693
10694    @Override
10695    public Rect getTaskBounds(int taskId) {
10696        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10697        long ident = Binder.clearCallingIdentity();
10698        Rect rect = new Rect();
10699        try {
10700            synchronized (this) {
10701                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10702                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10703                if (task == null) {
10704                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10705                    return rect;
10706                }
10707                if (task.getStack() != null) {
10708                    // Return the bounds from window manager since it will be adjusted for various
10709                    // things like the presense of a docked stack for tasks that aren't resizeable.
10710                    task.getWindowContainerBounds(rect);
10711                } else {
10712                    // Task isn't in window manager yet since it isn't associated with a stack.
10713                    // Return the persist value from activity manager
10714                    if (!task.matchParentBounds()) {
10715                        rect.set(task.getBounds());
10716                    } else if (task.mLastNonFullscreenBounds != null) {
10717                        rect.set(task.mLastNonFullscreenBounds);
10718                    }
10719                }
10720            }
10721        } finally {
10722            Binder.restoreCallingIdentity(ident);
10723        }
10724        return rect;
10725    }
10726
10727    @Override
10728    public void cancelTaskWindowTransition(int taskId) {
10729        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10730                "cancelTaskWindowTransition()");
10731        final long ident = Binder.clearCallingIdentity();
10732        try {
10733            synchronized (this) {
10734                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10735                        MATCH_TASK_IN_STACKS_ONLY);
10736                if (task == null) {
10737                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10738                    return;
10739                }
10740                task.cancelWindowTransition();
10741            }
10742        } finally {
10743            Binder.restoreCallingIdentity(ident);
10744        }
10745    }
10746
10747    @Override
10748    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10749        enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10750        final long ident = Binder.clearCallingIdentity();
10751        try {
10752            final TaskRecord task;
10753            synchronized (this) {
10754                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10755                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10756                if (task == null) {
10757                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10758                    return null;
10759                }
10760            }
10761            // Don't call this while holding the lock as this operation might hit the disk.
10762            return task.getSnapshot(reducedResolution);
10763        } finally {
10764            Binder.restoreCallingIdentity(ident);
10765        }
10766    }
10767
10768    @Override
10769    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10770        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10771                userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
10772
10773        final File passedIconFile = new File(filePath);
10774        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10775                passedIconFile.getName());
10776        if (!legitIconFile.getPath().equals(filePath)
10777                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10778            throw new IllegalArgumentException("Bad file path: " + filePath
10779                    + " passed for userId " + userId);
10780        }
10781        return mRecentTasks.getTaskDescriptionIcon(filePath);
10782    }
10783
10784    @Override
10785    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10786            throws RemoteException {
10787        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
10788        final ActivityOptions activityOptions = safeOptions != null
10789                ? safeOptions.getOptions(mStackSupervisor)
10790                : null;
10791        if (activityOptions == null
10792                || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
10793                || activityOptions.getCustomInPlaceResId() == 0) {
10794            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10795                    "with valid animation");
10796        }
10797        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10798        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10799                activityOptions.getCustomInPlaceResId());
10800        mWindowManager.executeAppTransition();
10801    }
10802
10803    @Override
10804    public void removeStack(int stackId) {
10805        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
10806        synchronized (this) {
10807            final long ident = Binder.clearCallingIdentity();
10808            try {
10809                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10810                if (stack == null) {
10811                    Slog.w(TAG, "removeStack: No stack with id=" + stackId);
10812                    return;
10813                }
10814                if (!stack.isActivityTypeStandardOrUndefined()) {
10815                    throw new IllegalArgumentException(
10816                            "Removing non-standard stack is not allowed.");
10817                }
10818                mStackSupervisor.removeStack(stack);
10819            } finally {
10820                Binder.restoreCallingIdentity(ident);
10821            }
10822        }
10823    }
10824
10825    /**
10826     * Removes stacks in the input windowing modes from the system if they are of activity type
10827     * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
10828     */
10829    @Override
10830    public void removeStacksInWindowingModes(int[] windowingModes) {
10831        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10832                "removeStacksInWindowingModes()");
10833        synchronized (this) {
10834            final long ident = Binder.clearCallingIdentity();
10835            try {
10836                mStackSupervisor.removeStacksInWindowingModes(windowingModes);
10837            } finally {
10838                Binder.restoreCallingIdentity(ident);
10839            }
10840        }
10841    }
10842
10843    @Override
10844    public void removeStacksWithActivityTypes(int[] activityTypes) {
10845        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10846                "removeStacksWithActivityTypes()");
10847        synchronized (this) {
10848            final long ident = Binder.clearCallingIdentity();
10849            try {
10850                mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
10851            } finally {
10852                Binder.restoreCallingIdentity(ident);
10853            }
10854        }
10855    }
10856
10857    @Override
10858    public void moveStackToDisplay(int stackId, int displayId) {
10859        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10860
10861        synchronized (this) {
10862            final long ident = Binder.clearCallingIdentity();
10863            try {
10864                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10865                        + " to displayId=" + displayId);
10866                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10867            } finally {
10868                Binder.restoreCallingIdentity(ident);
10869            }
10870        }
10871    }
10872
10873    @Override
10874    public boolean removeTask(int taskId) {
10875        enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
10876        synchronized (this) {
10877            final long ident = Binder.clearCallingIdentity();
10878            try {
10879                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
10880                        "remove-task");
10881            } finally {
10882                Binder.restoreCallingIdentity(ident);
10883            }
10884        }
10885    }
10886
10887    /**
10888     * TODO: Add mController hook
10889     */
10890    @Override
10891    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10892        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10893
10894        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10895        synchronized(this) {
10896            moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
10897                    false /* fromRecents */);
10898        }
10899    }
10900
10901    void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
10902            boolean fromRecents) {
10903
10904        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10905                Binder.getCallingUid(), -1, -1, "Task to front")) {
10906            SafeActivityOptions.abort(options);
10907            return;
10908        }
10909        final long origId = Binder.clearCallingIdentity();
10910        try {
10911            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10912            if (task == null) {
10913                Slog.d(TAG, "Could not find task for id: "+ taskId);
10914                return;
10915            }
10916            if (mLockTaskController.isLockTaskModeViolation(task)) {
10917                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10918                return;
10919            }
10920            ActivityOptions realOptions = options != null
10921                    ? options.getOptions(mStackSupervisor)
10922                    : null;
10923            mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
10924                    false /* forceNonResizable */);
10925
10926            final ActivityRecord topActivity = task.getTopActivity();
10927            if (topActivity != null) {
10928
10929                // We are reshowing a task, use a starting window to hide the initial draw delay
10930                // so the transition can start earlier.
10931                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10932                        true /* taskSwitch */, fromRecents);
10933            }
10934        } finally {
10935            Binder.restoreCallingIdentity(origId);
10936        }
10937        SafeActivityOptions.abort(options);
10938    }
10939
10940    /**
10941     * Attempts to move a task backwards in z-order (the order of activities within the task is
10942     * unchanged).
10943     *
10944     * There are several possible results of this call:
10945     * - if the task is locked, then we will show the lock toast
10946     * - if there is a task behind the provided task, then that task is made visible and resumed as
10947     *   this task is moved to the back
10948     * - otherwise, if there are no other tasks in the stack:
10949     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10950     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10951     *       (depending on whether it is visible)
10952     *     - otherwise, we simply return home and hide this task
10953     *
10954     * @param token A reference to the activity we wish to move
10955     * @param nonRoot If false then this only works if the activity is the root
10956     *                of a task; if true it will work for any activity in a task.
10957     * @return Returns true if the move completed, false if not.
10958     */
10959    @Override
10960    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10961        enforceNotIsolatedCaller("moveActivityTaskToBack");
10962        synchronized(this) {
10963            final long origId = Binder.clearCallingIdentity();
10964            try {
10965                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10966                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10967                if (task != null) {
10968                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10969                }
10970            } finally {
10971                Binder.restoreCallingIdentity(origId);
10972            }
10973        }
10974        return false;
10975    }
10976
10977    @Override
10978    public void moveTaskBackwards(int task) {
10979        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10980                "moveTaskBackwards()");
10981
10982        synchronized(this) {
10983            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10984                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10985                return;
10986            }
10987            final long origId = Binder.clearCallingIdentity();
10988            moveTaskBackwardsLocked(task);
10989            Binder.restoreCallingIdentity(origId);
10990        }
10991    }
10992
10993    private final void moveTaskBackwardsLocked(int task) {
10994        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10995    }
10996
10997    @Override
10998    public int createStackOnDisplay(int displayId) throws RemoteException {
10999        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
11000        synchronized (this) {
11001            final ActivityDisplay display =
11002                    mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
11003            if (display == null) {
11004                return INVALID_STACK_ID;
11005            }
11006            // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
11007            final ActivityStack stack = display.createStack(
11008                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
11009                    ON_TOP);
11010            return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
11011        }
11012    }
11013
11014    @Override
11015    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
11016        synchronized (this) {
11017            final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
11018            if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
11019                return stack.mDisplayId;
11020            }
11021            return DEFAULT_DISPLAY;
11022        }
11023    }
11024
11025    @Override
11026    public void exitFreeformMode(IBinder token) throws RemoteException {
11027        synchronized (this) {
11028            long ident = Binder.clearCallingIdentity();
11029            try {
11030                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11031                if (r == null) {
11032                    throw new IllegalArgumentException(
11033                            "exitFreeformMode: No activity record matching token=" + token);
11034                }
11035
11036                final ActivityStack stack = r.getStack();
11037                if (stack == null || !stack.inFreeformWindowingMode()) {
11038                    throw new IllegalStateException(
11039                            "exitFreeformMode: You can only go fullscreen from freeform.");
11040                }
11041
11042                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11043            } finally {
11044                Binder.restoreCallingIdentity(ident);
11045            }
11046        }
11047    }
11048
11049    @Override
11050    public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
11051        if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
11052            setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
11053                    toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
11054            return;
11055        }
11056        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
11057        synchronized (this) {
11058            final long ident = Binder.clearCallingIdentity();
11059            try {
11060                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11061                if (task == null) {
11062                    Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
11063                    return;
11064                }
11065
11066                if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
11067                        + " to windowingMode=" + windowingMode + " toTop=" + toTop);
11068
11069                if (!task.isActivityTypeStandardOrUndefined()) {
11070                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11071                            + " non-standard task " + taskId + " to windowing mode="
11072                            + windowingMode);
11073                }
11074
11075                final ActivityStack stack = task.getStack();
11076                if (toTop) {
11077                    stack.moveToFront("setTaskWindowingMode", task);
11078                }
11079                stack.setWindowingMode(windowingMode);
11080            } finally {
11081                Binder.restoreCallingIdentity(ident);
11082            }
11083        }
11084    }
11085
11086    /**
11087     * Moves the specified task to the primary-split-screen stack.
11088     *
11089     * @param taskId Id of task to move.
11090     * @param createMode The mode the primary split screen stack should be created in if it doesn't
11091     *                   exist already. See
11092     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
11093     *                   and
11094     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
11095     * @param toTop If the task and stack should be moved to the top.
11096     * @param animate Whether we should play an animation for the moving the task.
11097     * @param initialBounds If the primary stack gets created, it will use these bounds for the
11098     *                      stack. Pass {@code null} to use default bounds.
11099     * @param showRecents If the recents activity should be shown on the other side of the task
11100     *                    going into split-screen mode.
11101     */
11102    @Override
11103    public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
11104            boolean animate, Rect initialBounds, boolean showRecents) {
11105        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11106                "setTaskWindowingModeSplitScreenPrimary()");
11107        synchronized (this) {
11108            long ident = Binder.clearCallingIdentity();
11109            try {
11110                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11111                if (task == null) {
11112                    Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
11113                    return false;
11114                }
11115                if (DEBUG_STACK) Slog.d(TAG_STACK,
11116                        "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
11117                        + " to createMode=" + createMode + " toTop=" + toTop);
11118                if (!task.isActivityTypeStandardOrUndefined()) {
11119                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11120                            + " non-standard task " + taskId + " to split-screen windowing mode");
11121                }
11122
11123                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
11124                final int windowingMode = task.getWindowingMode();
11125                final ActivityStack stack = task.getStack();
11126                if (toTop) {
11127                    stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
11128                }
11129                stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
11130                        false /* enteringSplitScreenMode */);
11131                return windowingMode != task.getWindowingMode();
11132            } finally {
11133                Binder.restoreCallingIdentity(ident);
11134            }
11135        }
11136    }
11137
11138    @Override
11139    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
11140        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
11141        synchronized (this) {
11142            long ident = Binder.clearCallingIdentity();
11143            try {
11144                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11145                if (task == null) {
11146                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
11147                    return;
11148                }
11149
11150                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
11151                        + " to stackId=" + stackId + " toTop=" + toTop);
11152
11153                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11154                if (stack == null) {
11155                    throw new IllegalStateException(
11156                            "moveTaskToStack: No stack for stackId=" + stackId);
11157                }
11158                if (!stack.isActivityTypeStandardOrUndefined()) {
11159                    throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
11160                            + taskId + " to stack " + stackId);
11161                }
11162                if (stack.inSplitScreenPrimaryWindowingMode()) {
11163                    mWindowManager.setDockedStackCreateState(
11164                            SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
11165                }
11166                task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
11167                        "moveTaskToStack");
11168            } finally {
11169                Binder.restoreCallingIdentity(ident);
11170            }
11171        }
11172    }
11173
11174    /**
11175     * Dismisses split-screen multi-window mode.
11176     * @param toTop If true the current primary split-screen stack will be placed or left on top.
11177     */
11178    @Override
11179    public void dismissSplitScreenMode(boolean toTop) {
11180        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
11181        final long ident = Binder.clearCallingIdentity();
11182        try {
11183            synchronized (this) {
11184                final ActivityStack stack =
11185                        mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
11186                if (stack == null) {
11187                    Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
11188                    return;
11189                }
11190
11191                if (toTop) {
11192                    // Caller wants the current split-screen primary stack to be the top stack after
11193                    // it goes fullscreen, so move it to the front.
11194                    stack.moveToFront("dismissSplitScreenMode");
11195                } else if (mStackSupervisor.isFocusedStack(stack)) {
11196                    // In this case the current split-screen primary stack shouldn't be the top
11197                    // stack after it goes fullscreen, but it current has focus, so we move the
11198                    // focus to the top-most split-screen secondary stack next to it.
11199                    final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
11200                            WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
11201                    if (otherStack != null) {
11202                        otherStack.moveToFront("dismissSplitScreenMode_other");
11203                    }
11204                }
11205
11206                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11207            }
11208        } finally {
11209            Binder.restoreCallingIdentity(ident);
11210        }
11211    }
11212
11213    /**
11214     * Dismisses Pip
11215     * @param animate True if the dismissal should be animated.
11216     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
11217     *                          default animation duration should be used.
11218     */
11219    @Override
11220    public void dismissPip(boolean animate, int animationDuration) {
11221        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
11222        final long ident = Binder.clearCallingIdentity();
11223        try {
11224            synchronized (this) {
11225                final PinnedActivityStack stack =
11226                        mStackSupervisor.getDefaultDisplay().getPinnedStack();
11227                if (stack == null) {
11228                    Slog.w(TAG, "dismissPip: pinned stack not found.");
11229                    return;
11230                }
11231                if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11232                    throw new IllegalArgumentException("Stack: " + stack
11233                            + " doesn't support animated resize.");
11234                }
11235                if (animate) {
11236                    stack.animateResizePinnedStack(null /* sourceHintBounds */,
11237                            null /* destBounds */, animationDuration, false /* fromFullscreen */);
11238                } else {
11239                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
11240                }
11241            }
11242        } finally {
11243            Binder.restoreCallingIdentity(ident);
11244        }
11245    }
11246
11247    /**
11248     * Moves the top activity in the input stackId to the pinned stack.
11249     *
11250     * @param stackId Id of stack to move the top activity to pinned stack.
11251     * @param bounds Bounds to use for pinned stack.
11252     *
11253     * @return True if the top activity of the input stack was successfully moved to the pinned
11254     *          stack.
11255     */
11256    @Override
11257    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
11258        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11259                "moveTopActivityToPinnedStack()");
11260        synchronized (this) {
11261            if (!mSupportsPictureInPicture) {
11262                throw new IllegalStateException("moveTopActivityToPinnedStack:"
11263                        + "Device doesn't support picture-in-picture mode");
11264            }
11265
11266            long ident = Binder.clearCallingIdentity();
11267            try {
11268                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
11269            } finally {
11270                Binder.restoreCallingIdentity(ident);
11271            }
11272        }
11273    }
11274
11275    @Override
11276    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
11277            boolean preserveWindows, boolean animate, int animationDuration) {
11278        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
11279        long ident = Binder.clearCallingIdentity();
11280        try {
11281            synchronized (this) {
11282                if (animate) {
11283                    final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
11284                    if (stack == null) {
11285                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11286                        return;
11287                    }
11288                    if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11289                        throw new IllegalArgumentException("Stack: " + stackId
11290                                + " doesn't support animated resize.");
11291                    }
11292                    stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
11293                            animationDuration, false /* fromFullscreen */);
11294                } else {
11295                    final ActivityStack stack = mStackSupervisor.getStack(stackId);
11296                    if (stack == null) {
11297                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11298                        return;
11299                    }
11300                    mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
11301                            null /* tempTaskInsetBounds */, preserveWindows,
11302                            allowResizeInDockedMode, !DEFER_RESUME);
11303                }
11304            }
11305        } finally {
11306            Binder.restoreCallingIdentity(ident);
11307        }
11308    }
11309
11310    @Override
11311    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
11312            Rect tempDockedTaskInsetBounds,
11313            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
11314        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
11315        long ident = Binder.clearCallingIdentity();
11316        try {
11317            synchronized (this) {
11318                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
11319                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
11320                        PRESERVE_WINDOWS);
11321            }
11322        } finally {
11323            Binder.restoreCallingIdentity(ident);
11324        }
11325    }
11326
11327    @Override
11328    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
11329        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
11330        final long ident = Binder.clearCallingIdentity();
11331        try {
11332            synchronized (this) {
11333                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
11334            }
11335        } finally {
11336            Binder.restoreCallingIdentity(ident);
11337        }
11338    }
11339
11340    /**
11341     * Try to place task to provided position. The final position might be different depending on
11342     * current user and stacks state. The task will be moved to target stack if it's currently in
11343     * different stack.
11344     */
11345    @Override
11346    public void positionTaskInStack(int taskId, int stackId, int position) {
11347        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
11348        synchronized (this) {
11349            long ident = Binder.clearCallingIdentity();
11350            try {
11351                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
11352                        + taskId + " in stackId=" + stackId + " at position=" + position);
11353                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11354                if (task == null) {
11355                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
11356                            + taskId);
11357                }
11358
11359                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11360
11361                if (stack == null) {
11362                    throw new IllegalArgumentException("positionTaskInStack: no stack for id="
11363                            + stackId);
11364                }
11365                if (!stack.isActivityTypeStandardOrUndefined()) {
11366                    throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
11367                            + " the position of task " + taskId + " in/to non-standard stack");
11368                }
11369
11370                // TODO: Have the callers of this API call a separate reparent method if that is
11371                // what they intended to do vs. having this method also do reparenting.
11372                if (task.getStack() == stack) {
11373                    // Change position in current stack.
11374                    stack.positionChildAt(task, position);
11375                } else {
11376                    // Reparent to new stack.
11377                    task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
11378                            !DEFER_RESUME, "positionTaskInStack");
11379                }
11380            } finally {
11381                Binder.restoreCallingIdentity(ident);
11382            }
11383        }
11384    }
11385
11386    @Override
11387    public List<StackInfo> getAllStackInfos() {
11388        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
11389        long ident = Binder.clearCallingIdentity();
11390        try {
11391            synchronized (this) {
11392                return mStackSupervisor.getAllStackInfosLocked();
11393            }
11394        } finally {
11395            Binder.restoreCallingIdentity(ident);
11396        }
11397    }
11398
11399    @Override
11400    public StackInfo getStackInfo(int windowingMode, int activityType) {
11401        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
11402        long ident = Binder.clearCallingIdentity();
11403        try {
11404            synchronized (this) {
11405                return mStackSupervisor.getStackInfo(windowingMode, activityType);
11406            }
11407        } finally {
11408            Binder.restoreCallingIdentity(ident);
11409        }
11410    }
11411
11412    @Override
11413    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
11414        synchronized(this) {
11415            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
11416        }
11417    }
11418
11419    @Override
11420    public void updateDeviceOwner(String packageName) {
11421        final int callingUid = Binder.getCallingUid();
11422        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11423            throw new SecurityException("updateDeviceOwner called from non-system process");
11424        }
11425        synchronized (this) {
11426            mDeviceOwnerName = packageName;
11427        }
11428    }
11429
11430    @Override
11431    public void updateLockTaskPackages(int userId, String[] packages) {
11432        final int callingUid = Binder.getCallingUid();
11433        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11434            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11435                    "updateLockTaskPackages()");
11436        }
11437        synchronized (this) {
11438            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
11439                    Arrays.toString(packages));
11440            mLockTaskController.updateLockTaskPackages(userId, packages);
11441        }
11442    }
11443
11444    @Override
11445    public void updateLockTaskFeatures(int userId, int flags) {
11446        final int callingUid = Binder.getCallingUid();
11447        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11448            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11449                    "updateLockTaskFeatures()");
11450        }
11451        synchronized (this) {
11452            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
11453                    Integer.toHexString(flags));
11454            mLockTaskController.updateLockTaskFeatures(userId, flags);
11455        }
11456    }
11457
11458    private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
11459        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
11460        if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
11461            return;
11462        }
11463
11464        final ActivityStack stack = mStackSupervisor.getFocusedStack();
11465        if (stack == null || task != stack.topTask()) {
11466            throw new IllegalArgumentException("Invalid task, not in foreground");
11467        }
11468
11469        // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
11470        // system or a specific app.
11471        // * System-initiated requests will only start the pinned mode (screen pinning)
11472        // * App-initiated requests
11473        //   - will put the device in fully locked mode (LockTask), if the app is whitelisted
11474        //   - will start the pinned mode, otherwise
11475        final int callingUid = Binder.getCallingUid();
11476        long ident = Binder.clearCallingIdentity();
11477        try {
11478            // When a task is locked, dismiss the pinned stack if it exists
11479            mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
11480
11481            mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
11482        } finally {
11483            Binder.restoreCallingIdentity(ident);
11484        }
11485    }
11486
11487    @Override
11488    public void startLockTaskModeByToken(IBinder token) {
11489        synchronized (this) {
11490            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11491            if (r == null) {
11492                return;
11493            }
11494            startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
11495        }
11496    }
11497
11498    @Override
11499    public void startSystemLockTaskMode(int taskId) throws RemoteException {
11500        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11501        // This makes inner call to look as if it was initiated by system.
11502        long ident = Binder.clearCallingIdentity();
11503        try {
11504            synchronized (this) {
11505                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11506
11507                // When starting lock task mode the stack must be in front and focused
11508                task.getStack().moveToFront("startSystemLockTaskMode");
11509                startLockTaskModeLocked(task, true /* isSystemCaller */);
11510            }
11511        } finally {
11512            Binder.restoreCallingIdentity(ident);
11513        }
11514    }
11515
11516    @Override
11517    public void stopLockTaskModeByToken(IBinder token) {
11518        synchronized (this) {
11519            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11520            if (r == null) {
11521                return;
11522            }
11523            stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
11524        }
11525    }
11526
11527    /**
11528     * This API should be called by SystemUI only when user perform certain action to dismiss
11529     * lock task mode. We should only dismiss pinned lock task mode in this case.
11530     */
11531    @Override
11532    public void stopSystemLockTaskMode() throws RemoteException {
11533        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
11534        stopLockTaskModeInternal(null, true /* isSystemCaller */);
11535    }
11536
11537    private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
11538        final int callingUid = Binder.getCallingUid();
11539        long ident = Binder.clearCallingIdentity();
11540        try {
11541            synchronized (this) {
11542                mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
11543            }
11544            // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
11545            // task and jumping straight into a call in the case of emergency call back.
11546            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11547            if (tm != null) {
11548                tm.showInCallScreen(false);
11549            }
11550        } finally {
11551            Binder.restoreCallingIdentity(ident);
11552        }
11553    }
11554
11555    @Override
11556    public boolean isInLockTaskMode() {
11557        return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
11558    }
11559
11560    @Override
11561    public int getLockTaskModeState() {
11562        synchronized (this) {
11563            return mLockTaskController.getLockTaskModeState();
11564        }
11565    }
11566
11567    @Override
11568    public void showLockTaskEscapeMessage(IBinder token) {
11569        synchronized (this) {
11570            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11571            if (r == null) {
11572                return;
11573            }
11574            mLockTaskController.showLockTaskToast();
11575        }
11576    }
11577
11578    @Override
11579    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11580            throws RemoteException {
11581        synchronized (this) {
11582            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11583            if (r == null) {
11584                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11585                        + token);
11586                return;
11587            }
11588            final long origId = Binder.clearCallingIdentity();
11589            try {
11590                r.setDisablePreviewScreenshots(disable);
11591            } finally {
11592                Binder.restoreCallingIdentity(origId);
11593            }
11594        }
11595    }
11596
11597    // =========================================================
11598    // CONTENT PROVIDERS
11599    // =========================================================
11600
11601    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11602        List<ProviderInfo> providers = null;
11603        try {
11604            providers = AppGlobals.getPackageManager()
11605                    .queryContentProviders(app.processName, app.uid,
11606                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11607                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11608                    .getList();
11609        } catch (RemoteException ex) {
11610        }
11611        if (DEBUG_MU) Slog.v(TAG_MU,
11612                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11613        int userId = app.userId;
11614        if (providers != null) {
11615            int N = providers.size();
11616            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11617            for (int i=0; i<N; i++) {
11618                // TODO: keep logic in sync with installEncryptionUnawareProviders
11619                ProviderInfo cpi =
11620                    (ProviderInfo)providers.get(i);
11621                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11622                        cpi.name, cpi.flags);
11623                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11624                    // This is a singleton provider, but a user besides the
11625                    // default user is asking to initialize a process it runs
11626                    // in...  well, no, it doesn't actually run in this process,
11627                    // it runs in the process of the default user.  Get rid of it.
11628                    providers.remove(i);
11629                    N--;
11630                    i--;
11631                    continue;
11632                }
11633
11634                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11635                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11636                if (cpr == null) {
11637                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11638                    mProviderMap.putProviderByClass(comp, cpr);
11639                }
11640                if (DEBUG_MU) Slog.v(TAG_MU,
11641                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11642                app.pubProviders.put(cpi.name, cpr);
11643                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11644                    // Don't add this if it is a platform component that is marked
11645                    // to run in multiple processes, because this is actually
11646                    // part of the framework so doesn't make sense to track as a
11647                    // separate apk in the process.
11648                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11649                            mProcessStats);
11650                }
11651                notifyPackageUse(cpi.applicationInfo.packageName,
11652                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11653            }
11654        }
11655        return providers;
11656    }
11657
11658    /**
11659     * Check if the calling UID has a possible chance at accessing the provider
11660     * at the given authority and user.
11661     */
11662    public String checkContentProviderAccess(String authority, int userId) {
11663        if (userId == UserHandle.USER_ALL) {
11664            mContext.enforceCallingOrSelfPermission(
11665                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11666            userId = UserHandle.getCallingUserId();
11667        }
11668
11669        ProviderInfo cpi = null;
11670        try {
11671            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11672                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11673                            | PackageManager.MATCH_DISABLED_COMPONENTS
11674                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11675                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11676                    userId);
11677        } catch (RemoteException ignored) {
11678        }
11679        if (cpi == null) {
11680            return "Failed to find provider " + authority + " for user " + userId
11681                    + "; expected to find a valid ContentProvider for this authority";
11682        }
11683
11684        ProcessRecord r = null;
11685        synchronized (mPidsSelfLocked) {
11686            r = mPidsSelfLocked.get(Binder.getCallingPid());
11687        }
11688        if (r == null) {
11689            return "Failed to find PID " + Binder.getCallingPid();
11690        }
11691
11692        synchronized (this) {
11693            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11694        }
11695    }
11696
11697    /**
11698     * Check if {@link ProcessRecord} has a possible chance at accessing the
11699     * given {@link ProviderInfo}. Final permission checking is always done
11700     * in {@link ContentProvider}.
11701     */
11702    private final String checkContentProviderPermissionLocked(
11703            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11704        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11705        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11706        boolean checkedGrants = false;
11707        if (checkUser) {
11708            // Looking for cross-user grants before enforcing the typical cross-users permissions
11709            int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
11710            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11711                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11712                    return null;
11713                }
11714                checkedGrants = true;
11715            }
11716            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11717                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11718            if (userId != tmpTargetUserId) {
11719                // When we actually went to determine the final targer user ID, this ended
11720                // up different than our initial check for the authority.  This is because
11721                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11722                // SELF.  So we need to re-check the grants again.
11723                checkedGrants = false;
11724            }
11725        }
11726        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11727                cpi.applicationInfo.uid, cpi.exported)
11728                == PackageManager.PERMISSION_GRANTED) {
11729            return null;
11730        }
11731        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11732                cpi.applicationInfo.uid, cpi.exported)
11733                == PackageManager.PERMISSION_GRANTED) {
11734            return null;
11735        }
11736
11737        PathPermission[] pps = cpi.pathPermissions;
11738        if (pps != null) {
11739            int i = pps.length;
11740            while (i > 0) {
11741                i--;
11742                PathPermission pp = pps[i];
11743                String pprperm = pp.getReadPermission();
11744                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11745                        cpi.applicationInfo.uid, cpi.exported)
11746                        == PackageManager.PERMISSION_GRANTED) {
11747                    return null;
11748                }
11749                String ppwperm = pp.getWritePermission();
11750                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11751                        cpi.applicationInfo.uid, cpi.exported)
11752                        == PackageManager.PERMISSION_GRANTED) {
11753                    return null;
11754                }
11755            }
11756        }
11757        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11758            return null;
11759        }
11760
11761        final String suffix;
11762        if (!cpi.exported) {
11763            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11764        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11765            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11766        } else {
11767            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11768        }
11769        final String msg = "Permission Denial: opening provider " + cpi.name
11770                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11771                + ", uid=" + callingUid + ")" + suffix;
11772        Slog.w(TAG, msg);
11773        return msg;
11774    }
11775
11776    /**
11777     * Returns if the ContentProvider has granted a uri to callingUid
11778     */
11779    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11780        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11781        if (perms != null) {
11782            for (int i=perms.size()-1; i>=0; i--) {
11783                GrantUri grantUri = perms.keyAt(i);
11784                if (grantUri.sourceUserId == userId || !checkUser) {
11785                    if (matchesProvider(grantUri.uri, cpi)) {
11786                        return true;
11787                    }
11788                }
11789            }
11790        }
11791        return false;
11792    }
11793
11794    /**
11795     * Returns true if the uri authority is one of the authorities specified in the provider.
11796     */
11797    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11798        String uriAuth = uri.getAuthority();
11799        String cpiAuth = cpi.authority;
11800        if (cpiAuth.indexOf(';') == -1) {
11801            return cpiAuth.equals(uriAuth);
11802        }
11803        String[] cpiAuths = cpiAuth.split(";");
11804        int length = cpiAuths.length;
11805        for (int i = 0; i < length; i++) {
11806            if (cpiAuths[i].equals(uriAuth)) return true;
11807        }
11808        return false;
11809    }
11810
11811    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11812            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11813        if (r != null) {
11814            for (int i=0; i<r.conProviders.size(); i++) {
11815                ContentProviderConnection conn = r.conProviders.get(i);
11816                if (conn.provider == cpr) {
11817                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11818                            "Adding provider requested by "
11819                            + r.processName + " from process "
11820                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11821                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11822                    if (stable) {
11823                        conn.stableCount++;
11824                        conn.numStableIncs++;
11825                    } else {
11826                        conn.unstableCount++;
11827                        conn.numUnstableIncs++;
11828                    }
11829                    return conn;
11830                }
11831            }
11832            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11833            if (stable) {
11834                conn.stableCount = 1;
11835                conn.numStableIncs = 1;
11836            } else {
11837                conn.unstableCount = 1;
11838                conn.numUnstableIncs = 1;
11839            }
11840            cpr.connections.add(conn);
11841            r.conProviders.add(conn);
11842            startAssociationLocked(r.uid, r.processName, r.curProcState,
11843                    cpr.uid, cpr.name, cpr.info.processName);
11844            return conn;
11845        }
11846        cpr.addExternalProcessHandleLocked(externalProcessToken);
11847        return null;
11848    }
11849
11850    boolean decProviderCountLocked(ContentProviderConnection conn,
11851            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11852        if (conn != null) {
11853            cpr = conn.provider;
11854            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11855                    "Removing provider requested by "
11856                    + conn.client.processName + " from process "
11857                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11858                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11859            if (stable) {
11860                conn.stableCount--;
11861            } else {
11862                conn.unstableCount--;
11863            }
11864            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11865                cpr.connections.remove(conn);
11866                conn.client.conProviders.remove(conn);
11867                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11868                    // The client is more important than last activity -- note the time this
11869                    // is happening, so we keep the old provider process around a bit as last
11870                    // activity to avoid thrashing it.
11871                    if (cpr.proc != null) {
11872                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11873                    }
11874                }
11875                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11876                return true;
11877            }
11878            return false;
11879        }
11880        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11881        return false;
11882    }
11883
11884    private void checkTime(long startTime, String where) {
11885        long now = SystemClock.uptimeMillis();
11886        if ((now-startTime) > 50) {
11887            // If we are taking more than 50ms, log about it.
11888            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11889        }
11890    }
11891
11892    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11893            PROC_SPACE_TERM,
11894            PROC_SPACE_TERM|PROC_PARENS,
11895            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11896    };
11897
11898    private final long[] mProcessStateStatsLongs = new long[1];
11899
11900    private boolean isProcessAliveLocked(ProcessRecord proc) {
11901        if (proc.pid <= 0) {
11902            if (DEBUG_OOM_ADJ) Slog.d(TAG, "Process hasn't started yet: " + proc);
11903            return false;
11904        }
11905        if (proc.procStatFile == null) {
11906            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11907        }
11908        mProcessStateStatsLongs[0] = 0;
11909        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11910                mProcessStateStatsLongs, null)) {
11911            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11912            return false;
11913        }
11914        final long state = mProcessStateStatsLongs[0];
11915        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11916                + (char)state);
11917        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11918    }
11919
11920    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11921            String name, IBinder token, boolean stable, int userId) {
11922        ContentProviderRecord cpr;
11923        ContentProviderConnection conn = null;
11924        ProviderInfo cpi = null;
11925
11926        synchronized(this) {
11927            long startTime = SystemClock.uptimeMillis();
11928
11929            ProcessRecord r = null;
11930            if (caller != null) {
11931                r = getRecordForAppLocked(caller);
11932                if (r == null) {
11933                    throw new SecurityException(
11934                            "Unable to find app for caller " + caller
11935                          + " (pid=" + Binder.getCallingPid()
11936                          + ") when getting content provider " + name);
11937                }
11938            }
11939
11940            boolean checkCrossUser = true;
11941
11942            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11943
11944            // First check if this content provider has been published...
11945            cpr = mProviderMap.getProviderByName(name, userId);
11946            // If that didn't work, check if it exists for user 0 and then
11947            // verify that it's a singleton provider before using it.
11948            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11949                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11950                if (cpr != null) {
11951                    cpi = cpr.info;
11952                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11953                            cpi.name, cpi.flags)
11954                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11955                        userId = UserHandle.USER_SYSTEM;
11956                        checkCrossUser = false;
11957                    } else {
11958                        cpr = null;
11959                        cpi = null;
11960                    }
11961                }
11962            }
11963
11964            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11965            if (providerRunning) {
11966                cpi = cpr.info;
11967                String msg;
11968                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11969                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11970                        != null) {
11971                    throw new SecurityException(msg);
11972                }
11973                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11974
11975                if (r != null && cpr.canRunHere(r)) {
11976                    // This provider has been published or is in the process
11977                    // of being published...  but it is also allowed to run
11978                    // in the caller's process, so don't make a connection
11979                    // and just let the caller instantiate its own instance.
11980                    ContentProviderHolder holder = cpr.newHolder(null);
11981                    // don't give caller the provider object, it needs
11982                    // to make its own.
11983                    holder.provider = null;
11984                    return holder;
11985                }
11986                // Don't expose providers between normal apps and instant apps
11987                try {
11988                    if (AppGlobals.getPackageManager()
11989                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11990                        return null;
11991                    }
11992                } catch (RemoteException e) {
11993                }
11994
11995                final long origId = Binder.clearCallingIdentity();
11996
11997                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11998
11999                // In this case the provider instance already exists, so we can
12000                // return it right away.
12001                conn = incProviderCountLocked(r, cpr, token, stable);
12002                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
12003                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12004                        // If this is a perceptible app accessing the provider,
12005                        // make sure to count it as being accessed and thus
12006                        // back up on the LRU list.  This is good because
12007                        // content providers are often expensive to start.
12008                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
12009                        updateLruProcessLocked(cpr.proc, false, null);
12010                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
12011                    }
12012                }
12013
12014                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
12015                final int verifiedAdj = cpr.proc.verifiedAdj;
12016                boolean success = updateOomAdjLocked(cpr.proc, true);
12017                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
12018                // if the process has been successfully adjusted.  So to reduce races with
12019                // it, we will check whether the process still exists.  Note that this doesn't
12020                // completely get rid of races with LMK killing the process, but should make
12021                // them much smaller.
12022                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
12023                    success = false;
12024                }
12025                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
12026                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
12027                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
12028                // NOTE: there is still a race here where a signal could be
12029                // pending on the process even though we managed to update its
12030                // adj level.  Not sure what to do about this, but at least
12031                // the race is now smaller.
12032                if (!success) {
12033                    // Uh oh...  it looks like the provider's process
12034                    // has been killed on us.  We need to wait for a new
12035                    // process to be started, and make sure its death
12036                    // doesn't kill our process.
12037                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
12038                            + " is crashing; detaching " + r);
12039                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
12040                    checkTime(startTime, "getContentProviderImpl: before appDied");
12041                    appDiedLocked(cpr.proc);
12042                    checkTime(startTime, "getContentProviderImpl: after appDied");
12043                    if (!lastRef) {
12044                        // This wasn't the last ref our process had on
12045                        // the provider...  we have now been killed, bail.
12046                        return null;
12047                    }
12048                    providerRunning = false;
12049                    conn = null;
12050                } else {
12051                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
12052                }
12053
12054                Binder.restoreCallingIdentity(origId);
12055            }
12056
12057            if (!providerRunning) {
12058                try {
12059                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
12060                    cpi = AppGlobals.getPackageManager().
12061                        resolveContentProvider(name,
12062                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
12063                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
12064                } catch (RemoteException ex) {
12065                }
12066                if (cpi == null) {
12067                    return null;
12068                }
12069                // If the provider is a singleton AND
12070                // (it's a call within the same user || the provider is a
12071                // privileged app)
12072                // Then allow connecting to the singleton provider
12073                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
12074                        cpi.name, cpi.flags)
12075                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
12076                if (singleton) {
12077                    userId = UserHandle.USER_SYSTEM;
12078                }
12079                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
12080                checkTime(startTime, "getContentProviderImpl: got app info for user");
12081
12082                String msg;
12083                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12084                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
12085                        != null) {
12086                    throw new SecurityException(msg);
12087                }
12088                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
12089
12090                if (!mProcessesReady
12091                        && !cpi.processName.equals("system")) {
12092                    // If this content provider does not run in the system
12093                    // process, and the system is not yet ready to run other
12094                    // processes, then fail fast instead of hanging.
12095                    throw new IllegalArgumentException(
12096                            "Attempt to launch content provider before system ready");
12097                }
12098
12099                // Make sure that the user who owns this provider is running.  If not,
12100                // we don't want to allow it to run.
12101                if (!mUserController.isUserRunning(userId, 0)) {
12102                    Slog.w(TAG, "Unable to launch app "
12103                            + cpi.applicationInfo.packageName + "/"
12104                            + cpi.applicationInfo.uid + " for provider "
12105                            + name + ": user " + userId + " is stopped");
12106                    return null;
12107                }
12108
12109                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
12110                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
12111                cpr = mProviderMap.getProviderByClass(comp, userId);
12112                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
12113                final boolean firstClass = cpr == null;
12114                if (firstClass) {
12115                    final long ident = Binder.clearCallingIdentity();
12116
12117                    // If permissions need a review before any of the app components can run,
12118                    // we return no provider and launch a review activity if the calling app
12119                    // is in the foreground.
12120                    if (mPermissionReviewRequired) {
12121                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
12122                            return null;
12123                        }
12124                    }
12125
12126                    try {
12127                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
12128                        ApplicationInfo ai =
12129                            AppGlobals.getPackageManager().
12130                                getApplicationInfo(
12131                                        cpi.applicationInfo.packageName,
12132                                        STOCK_PM_FLAGS, userId);
12133                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
12134                        if (ai == null) {
12135                            Slog.w(TAG, "No package info for content provider "
12136                                    + cpi.name);
12137                            return null;
12138                        }
12139                        ai = getAppInfoForUser(ai, userId);
12140                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
12141                    } catch (RemoteException ex) {
12142                        // pm is in same process, this will never happen.
12143                    } finally {
12144                        Binder.restoreCallingIdentity(ident);
12145                    }
12146                }
12147
12148                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
12149
12150                if (r != null && cpr.canRunHere(r)) {
12151                    // If this is a multiprocess provider, then just return its
12152                    // info and allow the caller to instantiate it.  Only do
12153                    // this if the provider is the same user as the caller's
12154                    // process, or can run as root (so can be in any process).
12155                    return cpr.newHolder(null);
12156                }
12157
12158                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
12159                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
12160                            + cpr.info.name + " callers=" + Debug.getCallers(6));
12161
12162                // This is single process, and our app is now connecting to it.
12163                // See if we are already in the process of launching this
12164                // provider.
12165                final int N = mLaunchingProviders.size();
12166                int i;
12167                for (i = 0; i < N; i++) {
12168                    if (mLaunchingProviders.get(i) == cpr) {
12169                        break;
12170                    }
12171                }
12172
12173                // If the provider is not already being launched, then get it
12174                // started.
12175                if (i >= N) {
12176                    final long origId = Binder.clearCallingIdentity();
12177
12178                    try {
12179                        // Content provider is now in use, its package can't be stopped.
12180                        try {
12181                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
12182                            AppGlobals.getPackageManager().setPackageStoppedState(
12183                                    cpr.appInfo.packageName, false, userId);
12184                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
12185                        } catch (RemoteException e) {
12186                        } catch (IllegalArgumentException e) {
12187                            Slog.w(TAG, "Failed trying to unstop package "
12188                                    + cpr.appInfo.packageName + ": " + e);
12189                        }
12190
12191                        // Use existing process if already started
12192                        checkTime(startTime, "getContentProviderImpl: looking for process record");
12193                        ProcessRecord proc = getProcessRecordLocked(
12194                                cpi.processName, cpr.appInfo.uid, false);
12195                        if (proc != null && proc.thread != null && !proc.killed) {
12196                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
12197                                    "Installing in existing process " + proc);
12198                            if (!proc.pubProviders.containsKey(cpi.name)) {
12199                                checkTime(startTime, "getContentProviderImpl: scheduling install");
12200                                proc.pubProviders.put(cpi.name, cpr);
12201                                try {
12202                                    proc.thread.scheduleInstallProvider(cpi);
12203                                } catch (RemoteException e) {
12204                                }
12205                            }
12206                        } else {
12207                            checkTime(startTime, "getContentProviderImpl: before start process");
12208                            proc = startProcessLocked(cpi.processName,
12209                                    cpr.appInfo, false, 0, "content provider",
12210                                    new ComponentName(cpi.applicationInfo.packageName,
12211                                            cpi.name), false, false, false);
12212                            checkTime(startTime, "getContentProviderImpl: after start process");
12213                            if (proc == null) {
12214                                Slog.w(TAG, "Unable to launch app "
12215                                        + cpi.applicationInfo.packageName + "/"
12216                                        + cpi.applicationInfo.uid + " for provider "
12217                                        + name + ": process is bad");
12218                                return null;
12219                            }
12220                        }
12221                        cpr.launchingApp = proc;
12222                        mLaunchingProviders.add(cpr);
12223                    } finally {
12224                        Binder.restoreCallingIdentity(origId);
12225                    }
12226                }
12227
12228                checkTime(startTime, "getContentProviderImpl: updating data structures");
12229
12230                // Make sure the provider is published (the same provider class
12231                // may be published under multiple names).
12232                if (firstClass) {
12233                    mProviderMap.putProviderByClass(comp, cpr);
12234                }
12235
12236                mProviderMap.putProviderByName(name, cpr);
12237                conn = incProviderCountLocked(r, cpr, token, stable);
12238                if (conn != null) {
12239                    conn.waiting = true;
12240                }
12241            }
12242            checkTime(startTime, "getContentProviderImpl: done!");
12243
12244            grantEphemeralAccessLocked(userId, null /*intent*/,
12245                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
12246        }
12247
12248        // Wait for the provider to be published...
12249        synchronized (cpr) {
12250            while (cpr.provider == null) {
12251                if (cpr.launchingApp == null) {
12252                    Slog.w(TAG, "Unable to launch app "
12253                            + cpi.applicationInfo.packageName + "/"
12254                            + cpi.applicationInfo.uid + " for provider "
12255                            + name + ": launching app became null");
12256                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
12257                            UserHandle.getUserId(cpi.applicationInfo.uid),
12258                            cpi.applicationInfo.packageName,
12259                            cpi.applicationInfo.uid, name);
12260                    return null;
12261                }
12262                try {
12263                    if (DEBUG_MU) Slog.v(TAG_MU,
12264                            "Waiting to start provider " + cpr
12265                            + " launchingApp=" + cpr.launchingApp);
12266                    if (conn != null) {
12267                        conn.waiting = true;
12268                    }
12269                    cpr.wait();
12270                } catch (InterruptedException ex) {
12271                } finally {
12272                    if (conn != null) {
12273                        conn.waiting = false;
12274                    }
12275                }
12276            }
12277        }
12278        return cpr != null ? cpr.newHolder(conn) : null;
12279    }
12280
12281    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
12282            ProcessRecord r, final int userId) {
12283        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
12284                cpi.packageName, userId)) {
12285
12286            final boolean callerForeground = r == null || r.setSchedGroup
12287                    != ProcessList.SCHED_GROUP_BACKGROUND;
12288
12289            // Show a permission review UI only for starting from a foreground app
12290            if (!callerForeground) {
12291                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
12292                        + cpi.packageName + " requires a permissions review");
12293                return false;
12294            }
12295
12296            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
12297            intent.addFlags(FLAG_ACTIVITY_NEW_TASK
12298                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
12299            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
12300
12301            if (DEBUG_PERMISSIONS_REVIEW) {
12302                Slog.i(TAG, "u" + userId + " Launching permission review "
12303                        + "for package " + cpi.packageName);
12304            }
12305
12306            final UserHandle userHandle = new UserHandle(userId);
12307            mHandler.post(new Runnable() {
12308                @Override
12309                public void run() {
12310                    mContext.startActivityAsUser(intent, userHandle);
12311                }
12312            });
12313
12314            return false;
12315        }
12316
12317        return true;
12318    }
12319
12320    /**
12321     * Returns the PackageManager. Used by classes hosted by {@link ActivityManagerService}. The
12322     * PackageManager could be unavailable at construction time and therefore needs to be accessed
12323     * on demand.
12324     */
12325    IPackageManager getPackageManager() {
12326        return AppGlobals.getPackageManager();
12327    }
12328
12329    ActivityStartController getActivityStartController() {
12330        return mActivityStartController;
12331    }
12332
12333    ClientLifecycleManager getLifecycleManager() {
12334        return mLifecycleManager;
12335    }
12336
12337    PackageManagerInternal getPackageManagerInternalLocked() {
12338        if (mPackageManagerInt == null) {
12339            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
12340        }
12341        return mPackageManagerInt;
12342    }
12343
12344    @Override
12345    public final ContentProviderHolder getContentProvider(
12346            IApplicationThread caller, String name, int userId, boolean stable) {
12347        enforceNotIsolatedCaller("getContentProvider");
12348        if (caller == null) {
12349            String msg = "null IApplicationThread when getting content provider "
12350                    + name;
12351            Slog.w(TAG, msg);
12352            throw new SecurityException(msg);
12353        }
12354        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
12355        // with cross-user grant.
12356        return getContentProviderImpl(caller, name, null, stable, userId);
12357    }
12358
12359    public ContentProviderHolder getContentProviderExternal(
12360            String name, int userId, IBinder token) {
12361        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12362            "Do not have permission in call getContentProviderExternal()");
12363        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12364                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
12365        return getContentProviderExternalUnchecked(name, token, userId);
12366    }
12367
12368    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
12369            IBinder token, int userId) {
12370        return getContentProviderImpl(null, name, token, true, userId);
12371    }
12372
12373    /**
12374     * Drop a content provider from a ProcessRecord's bookkeeping
12375     */
12376    public void removeContentProvider(IBinder connection, boolean stable) {
12377        enforceNotIsolatedCaller("removeContentProvider");
12378        long ident = Binder.clearCallingIdentity();
12379        try {
12380            synchronized (this) {
12381                ContentProviderConnection conn;
12382                try {
12383                    conn = (ContentProviderConnection)connection;
12384                } catch (ClassCastException e) {
12385                    String msg ="removeContentProvider: " + connection
12386                            + " not a ContentProviderConnection";
12387                    Slog.w(TAG, msg);
12388                    throw new IllegalArgumentException(msg);
12389                }
12390                if (conn == null) {
12391                    throw new NullPointerException("connection is null");
12392                }
12393                if (decProviderCountLocked(conn, null, null, stable)) {
12394                    updateOomAdjLocked();
12395                }
12396            }
12397        } finally {
12398            Binder.restoreCallingIdentity(ident);
12399        }
12400    }
12401
12402    public void removeContentProviderExternal(String name, IBinder token) {
12403        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12404            "Do not have permission in call removeContentProviderExternal()");
12405        int userId = UserHandle.getCallingUserId();
12406        long ident = Binder.clearCallingIdentity();
12407        try {
12408            removeContentProviderExternalUnchecked(name, token, userId);
12409        } finally {
12410            Binder.restoreCallingIdentity(ident);
12411        }
12412    }
12413
12414    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
12415        synchronized (this) {
12416            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
12417            if(cpr == null) {
12418                //remove from mProvidersByClass
12419                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
12420                return;
12421            }
12422
12423            //update content provider record entry info
12424            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
12425            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
12426            if (localCpr.hasExternalProcessHandles()) {
12427                if (localCpr.removeExternalProcessHandleLocked(token)) {
12428                    updateOomAdjLocked();
12429                } else {
12430                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
12431                            + " with no external reference for token: "
12432                            + token + ".");
12433                }
12434            } else {
12435                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
12436                        + " with no external references.");
12437            }
12438        }
12439    }
12440
12441    public final void publishContentProviders(IApplicationThread caller,
12442            List<ContentProviderHolder> providers) {
12443        if (providers == null) {
12444            return;
12445        }
12446
12447        enforceNotIsolatedCaller("publishContentProviders");
12448        synchronized (this) {
12449            final ProcessRecord r = getRecordForAppLocked(caller);
12450            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
12451            if (r == null) {
12452                throw new SecurityException(
12453                        "Unable to find app for caller " + caller
12454                      + " (pid=" + Binder.getCallingPid()
12455                      + ") when publishing content providers");
12456            }
12457
12458            final long origId = Binder.clearCallingIdentity();
12459
12460            final int N = providers.size();
12461            for (int i = 0; i < N; i++) {
12462                ContentProviderHolder src = providers.get(i);
12463                if (src == null || src.info == null || src.provider == null) {
12464                    continue;
12465                }
12466                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
12467                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
12468                if (dst != null) {
12469                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
12470                    mProviderMap.putProviderByClass(comp, dst);
12471                    String names[] = dst.info.authority.split(";");
12472                    for (int j = 0; j < names.length; j++) {
12473                        mProviderMap.putProviderByName(names[j], dst);
12474                    }
12475
12476                    int launchingCount = mLaunchingProviders.size();
12477                    int j;
12478                    boolean wasInLaunchingProviders = false;
12479                    for (j = 0; j < launchingCount; j++) {
12480                        if (mLaunchingProviders.get(j) == dst) {
12481                            mLaunchingProviders.remove(j);
12482                            wasInLaunchingProviders = true;
12483                            j--;
12484                            launchingCount--;
12485                        }
12486                    }
12487                    if (wasInLaunchingProviders) {
12488                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12489                    }
12490                    synchronized (dst) {
12491                        dst.provider = src.provider;
12492                        dst.proc = r;
12493                        dst.notifyAll();
12494                    }
12495                    updateOomAdjLocked(r, true);
12496                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12497                            src.info.authority);
12498                }
12499            }
12500
12501            Binder.restoreCallingIdentity(origId);
12502        }
12503    }
12504
12505    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12506        ContentProviderConnection conn;
12507        try {
12508            conn = (ContentProviderConnection)connection;
12509        } catch (ClassCastException e) {
12510            String msg ="refContentProvider: " + connection
12511                    + " not a ContentProviderConnection";
12512            Slog.w(TAG, msg);
12513            throw new IllegalArgumentException(msg);
12514        }
12515        if (conn == null) {
12516            throw new NullPointerException("connection is null");
12517        }
12518
12519        synchronized (this) {
12520            if (stable > 0) {
12521                conn.numStableIncs += stable;
12522            }
12523            stable = conn.stableCount + stable;
12524            if (stable < 0) {
12525                throw new IllegalStateException("stableCount < 0: " + stable);
12526            }
12527
12528            if (unstable > 0) {
12529                conn.numUnstableIncs += unstable;
12530            }
12531            unstable = conn.unstableCount + unstable;
12532            if (unstable < 0) {
12533                throw new IllegalStateException("unstableCount < 0: " + unstable);
12534            }
12535
12536            if ((stable+unstable) <= 0) {
12537                throw new IllegalStateException("ref counts can't go to zero here: stable="
12538                        + stable + " unstable=" + unstable);
12539            }
12540            conn.stableCount = stable;
12541            conn.unstableCount = unstable;
12542            return !conn.dead;
12543        }
12544    }
12545
12546    public void unstableProviderDied(IBinder connection) {
12547        ContentProviderConnection conn;
12548        try {
12549            conn = (ContentProviderConnection)connection;
12550        } catch (ClassCastException e) {
12551            String msg ="refContentProvider: " + connection
12552                    + " not a ContentProviderConnection";
12553            Slog.w(TAG, msg);
12554            throw new IllegalArgumentException(msg);
12555        }
12556        if (conn == null) {
12557            throw new NullPointerException("connection is null");
12558        }
12559
12560        // Safely retrieve the content provider associated with the connection.
12561        IContentProvider provider;
12562        synchronized (this) {
12563            provider = conn.provider.provider;
12564        }
12565
12566        if (provider == null) {
12567            // Um, yeah, we're way ahead of you.
12568            return;
12569        }
12570
12571        // Make sure the caller is being honest with us.
12572        if (provider.asBinder().pingBinder()) {
12573            // Er, no, still looks good to us.
12574            synchronized (this) {
12575                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12576                        + " says " + conn + " died, but we don't agree");
12577                return;
12578            }
12579        }
12580
12581        // Well look at that!  It's dead!
12582        synchronized (this) {
12583            if (conn.provider.provider != provider) {
12584                // But something changed...  good enough.
12585                return;
12586            }
12587
12588            ProcessRecord proc = conn.provider.proc;
12589            if (proc == null || proc.thread == null) {
12590                // Seems like the process is already cleaned up.
12591                return;
12592            }
12593
12594            // As far as we're concerned, this is just like receiving a
12595            // death notification...  just a bit prematurely.
12596            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12597                    + ") early provider death");
12598            final long ident = Binder.clearCallingIdentity();
12599            try {
12600                appDiedLocked(proc);
12601            } finally {
12602                Binder.restoreCallingIdentity(ident);
12603            }
12604        }
12605    }
12606
12607    @Override
12608    public void appNotRespondingViaProvider(IBinder connection) {
12609        enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
12610
12611        final ContentProviderConnection conn = (ContentProviderConnection) connection;
12612        if (conn == null) {
12613            Slog.w(TAG, "ContentProviderConnection is null");
12614            return;
12615        }
12616
12617        final ProcessRecord host = conn.provider.proc;
12618        if (host == null) {
12619            Slog.w(TAG, "Failed to find hosting ProcessRecord");
12620            return;
12621        }
12622
12623        mHandler.post(new Runnable() {
12624            @Override
12625            public void run() {
12626                mAppErrors.appNotResponding(host, null, null, false,
12627                        "ContentProvider not responding");
12628            }
12629        });
12630    }
12631
12632    public final void installSystemProviders() {
12633        List<ProviderInfo> providers;
12634        synchronized (this) {
12635            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12636            providers = generateApplicationProvidersLocked(app);
12637            if (providers != null) {
12638                for (int i=providers.size()-1; i>=0; i--) {
12639                    ProviderInfo pi = (ProviderInfo)providers.get(i);
12640                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12641                        Slog.w(TAG, "Not installing system proc provider " + pi.name
12642                                + ": not system .apk");
12643                        providers.remove(i);
12644                    }
12645                }
12646            }
12647        }
12648        if (providers != null) {
12649            mSystemThread.installSystemProviders(providers);
12650        }
12651
12652        mConstants.start(mContext.getContentResolver());
12653        mCoreSettingsObserver = new CoreSettingsObserver(this);
12654        mFontScaleSettingObserver = new FontScaleSettingObserver();
12655        mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
12656        GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
12657
12658        // Now that the settings provider is published we can consider sending
12659        // in a rescue party.
12660        RescueParty.onSettingsProviderPublished(mContext);
12661
12662        //mUsageStatsService.monitorPackages();
12663    }
12664
12665    void startPersistentApps(int matchFlags) {
12666        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12667
12668        synchronized (this) {
12669            try {
12670                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12671                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12672                for (ApplicationInfo app : apps) {
12673                    if (!"android".equals(app.packageName)) {
12674                        addAppLocked(app, null, false, null /* ABI override */);
12675                    }
12676                }
12677            } catch (RemoteException ex) {
12678            }
12679        }
12680    }
12681
12682    /**
12683     * When a user is unlocked, we need to install encryption-unaware providers
12684     * belonging to any running apps.
12685     */
12686    void installEncryptionUnawareProviders(int userId) {
12687        // We're only interested in providers that are encryption unaware, and
12688        // we don't care about uninstalled apps, since there's no way they're
12689        // running at this point.
12690        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12691
12692        synchronized (this) {
12693            final int NP = mProcessNames.getMap().size();
12694            for (int ip = 0; ip < NP; ip++) {
12695                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12696                final int NA = apps.size();
12697                for (int ia = 0; ia < NA; ia++) {
12698                    final ProcessRecord app = apps.valueAt(ia);
12699                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12700
12701                    final int NG = app.pkgList.size();
12702                    for (int ig = 0; ig < NG; ig++) {
12703                        try {
12704                            final String pkgName = app.pkgList.keyAt(ig);
12705                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12706                                    .getPackageInfo(pkgName, matchFlags, userId);
12707                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12708                                for (ProviderInfo pi : pkgInfo.providers) {
12709                                    // TODO: keep in sync with generateApplicationProvidersLocked
12710                                    final boolean processMatch = Objects.equals(pi.processName,
12711                                            app.processName) || pi.multiprocess;
12712                                    final boolean userMatch = isSingleton(pi.processName,
12713                                            pi.applicationInfo, pi.name, pi.flags)
12714                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12715                                    if (processMatch && userMatch) {
12716                                        Log.v(TAG, "Installing " + pi);
12717                                        app.thread.scheduleInstallProvider(pi);
12718                                    } else {
12719                                        Log.v(TAG, "Skipping " + pi);
12720                                    }
12721                                }
12722                            }
12723                        } catch (RemoteException ignored) {
12724                        }
12725                    }
12726                }
12727            }
12728        }
12729    }
12730
12731    /**
12732     * Allows apps to retrieve the MIME type of a URI.
12733     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12734     * users, then it does not need permission to access the ContentProvider.
12735     * Either, it needs cross-user uri grants.
12736     *
12737     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12738     *
12739     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12740     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12741     */
12742    public String getProviderMimeType(Uri uri, int userId) {
12743        enforceNotIsolatedCaller("getProviderMimeType");
12744        final String name = uri.getAuthority();
12745        int callingUid = Binder.getCallingUid();
12746        int callingPid = Binder.getCallingPid();
12747        long ident = 0;
12748        boolean clearedIdentity = false;
12749        userId = mUserController.unsafeConvertIncomingUser(userId);
12750        if (canClearIdentity(callingPid, callingUid, userId)) {
12751            clearedIdentity = true;
12752            ident = Binder.clearCallingIdentity();
12753        }
12754        ContentProviderHolder holder = null;
12755        try {
12756            holder = getContentProviderExternalUnchecked(name, null, userId);
12757            if (holder != null) {
12758                return holder.provider.getType(uri);
12759            }
12760        } catch (RemoteException e) {
12761            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12762            return null;
12763        } catch (Exception e) {
12764            Log.w(TAG, "Exception while determining type of " + uri, e);
12765            return null;
12766        } finally {
12767            // We need to clear the identity to call removeContentProviderExternalUnchecked
12768            if (!clearedIdentity) {
12769                ident = Binder.clearCallingIdentity();
12770            }
12771            try {
12772                if (holder != null) {
12773                    removeContentProviderExternalUnchecked(name, null, userId);
12774                }
12775            } finally {
12776                Binder.restoreCallingIdentity(ident);
12777            }
12778        }
12779
12780        return null;
12781    }
12782
12783    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12784        if (UserHandle.getUserId(callingUid) == userId) {
12785            return true;
12786        }
12787        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12788                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12789                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12790                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12791                return true;
12792        }
12793        return false;
12794    }
12795
12796    // =========================================================
12797    // GLOBAL MANAGEMENT
12798    // =========================================================
12799
12800    @GuardedBy("this")
12801    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12802            boolean isolated, int isolatedUid) {
12803        String proc = customProcess != null ? customProcess : info.processName;
12804        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12805        final int userId = UserHandle.getUserId(info.uid);
12806        int uid = info.uid;
12807        if (isolated) {
12808            if (isolatedUid == 0) {
12809                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12810                while (true) {
12811                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12812                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12813                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12814                    }
12815                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12816                    mNextIsolatedProcessUid++;
12817                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12818                        // No process for this uid, use it.
12819                        break;
12820                    }
12821                    stepsLeft--;
12822                    if (stepsLeft <= 0) {
12823                        return null;
12824                    }
12825                }
12826            } else {
12827                // Special case for startIsolatedProcess (internal only), where
12828                // the uid of the isolated process is specified by the caller.
12829                uid = isolatedUid;
12830            }
12831            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12832
12833            // Register the isolated UID with this application so BatteryStats knows to
12834            // attribute resource usage to the application.
12835            //
12836            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12837            // about the process state of the isolated UID *before* it is registered with the
12838            // owning application.
12839            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12840        }
12841        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12842        if (!mBooted && !mBooting
12843                && userId == UserHandle.USER_SYSTEM
12844                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12845            // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
12846            r.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
12847            r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
12848            r.persistent = true;
12849            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12850        }
12851        if (isolated && isolatedUid != 0) {
12852            // Special case for startIsolatedProcess (internal only) - assume the process
12853            // is required by the system server to prevent it being killed.
12854            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
12855        }
12856        addProcessNameLocked(r);
12857        return r;
12858    }
12859
12860    private boolean uidOnBackgroundWhitelist(final int uid) {
12861        final int appId = UserHandle.getAppId(uid);
12862        final int[] whitelist = mBackgroundAppIdWhitelist;
12863        final int N = whitelist.length;
12864        for (int i = 0; i < N; i++) {
12865            if (appId == whitelist[i]) {
12866                return true;
12867            }
12868        }
12869        return false;
12870    }
12871
12872    @Override
12873    public boolean isBackgroundRestricted(String packageName) {
12874        final int callingUid = Binder.getCallingUid();
12875        final IPackageManager pm = AppGlobals.getPackageManager();
12876        try {
12877            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
12878                    UserHandle.getUserId(callingUid));
12879            if (packageUid != callingUid) {
12880                throw new IllegalArgumentException("Uid " + callingUid
12881                        + " cannot query restriction state for package " + packageName);
12882            }
12883        } catch (RemoteException exc) {
12884            // Ignore.
12885        }
12886        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
12887                callingUid, packageName);
12888        return (mode != AppOpsManager.MODE_ALLOWED);
12889    }
12890
12891    @Override
12892    public void backgroundWhitelistUid(final int uid) {
12893        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12894            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12895        }
12896
12897        if (DEBUG_BACKGROUND_CHECK) {
12898            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12899        }
12900        synchronized (this) {
12901            final int N = mBackgroundAppIdWhitelist.length;
12902            int[] newList = new int[N+1];
12903            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12904            newList[N] = UserHandle.getAppId(uid);
12905            mBackgroundAppIdWhitelist = newList;
12906        }
12907    }
12908
12909    @GuardedBy("this")
12910    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12911            String abiOverride) {
12912        return addAppLocked(info, customProcess, isolated, false /* disableHiddenApiChecks */,
12913                abiOverride);
12914    }
12915
12916    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12917            boolean disableHiddenApiChecks, String abiOverride) {
12918        ProcessRecord app;
12919        if (!isolated) {
12920            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12921                    info.uid, true);
12922        } else {
12923            app = null;
12924        }
12925
12926        if (app == null) {
12927            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12928            updateLruProcessLocked(app, false, null);
12929            updateOomAdjLocked();
12930        }
12931
12932        // This package really, really can not be stopped.
12933        try {
12934            AppGlobals.getPackageManager().setPackageStoppedState(
12935                    info.packageName, false, UserHandle.getUserId(app.uid));
12936        } catch (RemoteException e) {
12937        } catch (IllegalArgumentException e) {
12938            Slog.w(TAG, "Failed trying to unstop package "
12939                    + info.packageName + ": " + e);
12940        }
12941
12942        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12943            app.persistent = true;
12944            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12945        }
12946        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12947            mPersistentStartingProcesses.add(app);
12948            startProcessLocked(app, "added application",
12949                    customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
12950                    abiOverride);
12951        }
12952
12953        return app;
12954    }
12955
12956    public void unhandledBack() {
12957        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12958                "unhandledBack()");
12959
12960        synchronized(this) {
12961            final long origId = Binder.clearCallingIdentity();
12962            try {
12963                getFocusedStack().unhandledBackLocked();
12964            } finally {
12965                Binder.restoreCallingIdentity(origId);
12966            }
12967        }
12968    }
12969
12970    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12971        enforceNotIsolatedCaller("openContentUri");
12972        final int userId = UserHandle.getCallingUserId();
12973        final Uri uri = Uri.parse(uriString);
12974        String name = uri.getAuthority();
12975        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12976        ParcelFileDescriptor pfd = null;
12977        if (cph != null) {
12978            // We record the binder invoker's uid in thread-local storage before
12979            // going to the content provider to open the file.  Later, in the code
12980            // that handles all permissions checks, we look for this uid and use
12981            // that rather than the Activity Manager's own uid.  The effect is that
12982            // we do the check against the caller's permissions even though it looks
12983            // to the content provider like the Activity Manager itself is making
12984            // the request.
12985            Binder token = new Binder();
12986            sCallerIdentity.set(new Identity(
12987                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12988            try {
12989                pfd = cph.provider.openFile(null, uri, "r", null, token);
12990            } catch (FileNotFoundException e) {
12991                // do nothing; pfd will be returned null
12992            } finally {
12993                // Ensure that whatever happens, we clean up the identity state
12994                sCallerIdentity.remove();
12995                // Ensure we're done with the provider.
12996                removeContentProviderExternalUnchecked(name, null, userId);
12997            }
12998        } else {
12999            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
13000        }
13001        return pfd;
13002    }
13003
13004    // Actually is sleeping or shutting down or whatever else in the future
13005    // is an inactive state.
13006    boolean isSleepingOrShuttingDownLocked() {
13007        return isSleepingLocked() || mShuttingDown;
13008    }
13009
13010    boolean isShuttingDownLocked() {
13011        return mShuttingDown;
13012    }
13013
13014    boolean isSleepingLocked() {
13015        return mSleeping;
13016    }
13017
13018    void onWakefulnessChanged(int wakefulness) {
13019        synchronized(this) {
13020            boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13021            boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13022            mWakefulness = wakefulness;
13023
13024            if (wasAwake != isAwake) {
13025                // Also update state in a special way for running foreground services UI.
13026                mServices.updateScreenStateLocked(isAwake);
13027                mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
13028                        .sendToTarget();
13029            }
13030        }
13031    }
13032
13033    @GuardedBy("this")
13034    void finishRunningVoiceLocked() {
13035        if (mRunningVoice != null) {
13036            mRunningVoice = null;
13037            mVoiceWakeLock.release();
13038            updateSleepIfNeededLocked();
13039        }
13040    }
13041
13042    void startTimeTrackingFocusedActivityLocked() {
13043        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
13044        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
13045            mCurAppTimeTracker.start(resumedActivity.packageName);
13046        }
13047    }
13048
13049    @GuardedBy("this")
13050    void updateSleepIfNeededLocked() {
13051        final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
13052        final boolean wasSleeping = mSleeping;
13053
13054        if (!shouldSleep) {
13055            // If wasSleeping is true, we need to wake up activity manager state from when
13056            // we started sleeping. In either case, we need to apply the sleep tokens, which
13057            // will wake up stacks or put them to sleep as appropriate.
13058            if (wasSleeping) {
13059                mSleeping = false;
13060                startTimeTrackingFocusedActivityLocked();
13061                mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
13062                mStackSupervisor.comeOutOfSleepIfNeededLocked();
13063            }
13064            mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
13065            if (wasSleeping) {
13066                updateOomAdjLocked();
13067            }
13068        } else if (!mSleeping && shouldSleep) {
13069            mSleeping = true;
13070            if (mCurAppTimeTracker != null) {
13071                mCurAppTimeTracker.stop();
13072            }
13073            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
13074            mStackSupervisor.goingToSleepLocked();
13075            updateOomAdjLocked();
13076        }
13077    }
13078
13079    /** Pokes the task persister. */
13080    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
13081        mRecentTasks.notifyTaskPersisterLocked(task, flush);
13082    }
13083
13084    /**
13085     * Notifies all listeners when the pinned stack animation starts.
13086     */
13087    @Override
13088    public void notifyPinnedStackAnimationStarted() {
13089        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
13090    }
13091
13092    /**
13093     * Notifies all listeners when the pinned stack animation ends.
13094     */
13095    @Override
13096    public void notifyPinnedStackAnimationEnded() {
13097        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
13098    }
13099
13100    @Override
13101    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
13102        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
13103    }
13104
13105    @Override
13106    public boolean shutdown(int timeout) {
13107        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
13108                != PackageManager.PERMISSION_GRANTED) {
13109            throw new SecurityException("Requires permission "
13110                    + android.Manifest.permission.SHUTDOWN);
13111        }
13112
13113        // TODO: Where should the corresponding '1' (start) write go?
13114        StatsLog.write(StatsLog.DEVICE_ON_STATUS_CHANGED,
13115                StatsLog.DEVICE_ON_STATUS_CHANGED__STATE__OFF);
13116
13117        boolean timedout = false;
13118
13119        synchronized(this) {
13120            mShuttingDown = true;
13121            mStackSupervisor.prepareForShutdownLocked();
13122            updateEventDispatchingLocked();
13123            timedout = mStackSupervisor.shutdownLocked(timeout);
13124        }
13125
13126        mAppOpsService.shutdown();
13127        if (mUsageStatsService != null) {
13128            mUsageStatsService.prepareShutdown();
13129        }
13130        mBatteryStatsService.shutdown();
13131        synchronized (this) {
13132            mProcessStats.shutdownLocked();
13133            notifyTaskPersisterLocked(null, true);
13134        }
13135
13136        return timedout;
13137    }
13138
13139    public final void activitySlept(IBinder token) {
13140        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
13141
13142        final long origId = Binder.clearCallingIdentity();
13143
13144        synchronized (this) {
13145            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13146            if (r != null) {
13147                mStackSupervisor.activitySleptLocked(r);
13148            }
13149        }
13150
13151        Binder.restoreCallingIdentity(origId);
13152    }
13153
13154    @GuardedBy("this")
13155    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
13156        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
13157        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
13158        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
13159            boolean wasRunningVoice = mRunningVoice != null;
13160            mRunningVoice = session;
13161            if (!wasRunningVoice) {
13162                mVoiceWakeLock.acquire();
13163                updateSleepIfNeededLocked();
13164            }
13165        }
13166    }
13167
13168    private void updateEventDispatchingLocked() {
13169        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
13170    }
13171
13172    @Override
13173    public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
13174        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
13175                != PackageManager.PERMISSION_GRANTED) {
13176            throw new SecurityException("Requires permission "
13177                    + android.Manifest.permission.DEVICE_POWER);
13178        }
13179
13180        synchronized(this) {
13181            long ident = Binder.clearCallingIdentity();
13182            try {
13183                mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
13184            } finally {
13185                Binder.restoreCallingIdentity(ident);
13186            }
13187        }
13188
13189        mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
13190                .sendToTarget();
13191    }
13192
13193    @Override
13194    public void notifyLockedProfile(@UserIdInt int userId) {
13195        try {
13196            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
13197                throw new SecurityException("Only privileged app can call notifyLockedProfile");
13198            }
13199        } catch (RemoteException ex) {
13200            throw new SecurityException("Fail to check is caller a privileged app", ex);
13201        }
13202
13203        synchronized (this) {
13204            final long ident = Binder.clearCallingIdentity();
13205            try {
13206                if (mUserController.shouldConfirmCredentials(userId)) {
13207                    if (mKeyguardController.isKeyguardLocked()) {
13208                        // Showing launcher to avoid user entering credential twice.
13209                        final int currentUserId = mUserController.getCurrentUserId();
13210                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
13211                    }
13212                    mStackSupervisor.lockAllProfileTasks(userId);
13213                }
13214            } finally {
13215                Binder.restoreCallingIdentity(ident);
13216            }
13217        }
13218    }
13219
13220    @Override
13221    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
13222        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
13223        synchronized (this) {
13224            final long ident = Binder.clearCallingIdentity();
13225            try {
13226                intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
13227                        FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
13228                        FLAG_ACTIVITY_TASK_ON_HOME);
13229                ActivityOptions activityOptions = options != null
13230                        ? new ActivityOptions(options)
13231                        : ActivityOptions.makeBasic();
13232                activityOptions.setLaunchTaskId(
13233                        mStackSupervisor.getHomeActivity().getTask().taskId);
13234                mContext.startActivityAsUser(intent, activityOptions.toBundle(),
13235                        UserHandle.CURRENT);
13236            } finally {
13237                Binder.restoreCallingIdentity(ident);
13238            }
13239        }
13240    }
13241
13242    @Override
13243    public void stopAppSwitches() {
13244        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
13245                != PackageManager.PERMISSION_GRANTED) {
13246            throw new SecurityException("viewquires permission "
13247                    + android.Manifest.permission.STOP_APP_SWITCHES);
13248        }
13249
13250        synchronized(this) {
13251            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
13252                    + APP_SWITCH_DELAY_TIME;
13253            mDidAppSwitch = false;
13254            mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
13255        }
13256    }
13257
13258    public void resumeAppSwitches() {
13259        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
13260                != PackageManager.PERMISSION_GRANTED) {
13261            throw new SecurityException("Requires permission "
13262                    + android.Manifest.permission.STOP_APP_SWITCHES);
13263        }
13264
13265        synchronized(this) {
13266            // Note that we don't execute any pending app switches... we will
13267            // let those wait until either the timeout, or the next start
13268            // activity request.
13269            mAppSwitchesAllowedTime = 0;
13270        }
13271    }
13272
13273    boolean checkAllowAppSwitchUid(int uid) {
13274        ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
13275        if (types != null) {
13276            for (int i = types.size() - 1; i >= 0; i--) {
13277                if (types.valueAt(i).intValue() == uid) {
13278                    return true;
13279                }
13280            }
13281        }
13282        return false;
13283    }
13284
13285    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
13286            int callingPid, int callingUid, String name) {
13287        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
13288            return true;
13289        }
13290
13291        int perm = checkComponentPermission(
13292                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
13293                sourceUid, -1, true);
13294        if (perm == PackageManager.PERMISSION_GRANTED) {
13295            return true;
13296        }
13297        if (checkAllowAppSwitchUid(sourceUid)) {
13298            return true;
13299        }
13300
13301        // If the actual IPC caller is different from the logical source, then
13302        // also see if they are allowed to control app switches.
13303        if (callingUid != -1 && callingUid != sourceUid) {
13304            perm = checkComponentPermission(
13305                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
13306                    callingUid, -1, true);
13307            if (perm == PackageManager.PERMISSION_GRANTED) {
13308                return true;
13309            }
13310            if (checkAllowAppSwitchUid(callingUid)) {
13311                return true;
13312            }
13313        }
13314
13315        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
13316        return false;
13317    }
13318
13319    public void setDebugApp(String packageName, boolean waitForDebugger,
13320            boolean persistent) {
13321        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
13322                "setDebugApp()");
13323
13324        long ident = Binder.clearCallingIdentity();
13325        try {
13326            // Note that this is not really thread safe if there are multiple
13327            // callers into it at the same time, but that's not a situation we
13328            // care about.
13329            if (persistent) {
13330                final ContentResolver resolver = mContext.getContentResolver();
13331                Settings.Global.putString(
13332                    resolver, Settings.Global.DEBUG_APP,
13333                    packageName);
13334                Settings.Global.putInt(
13335                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
13336                    waitForDebugger ? 1 : 0);
13337            }
13338
13339            synchronized (this) {
13340                if (!persistent) {
13341                    mOrigDebugApp = mDebugApp;
13342                    mOrigWaitForDebugger = mWaitForDebugger;
13343                }
13344                mDebugApp = packageName;
13345                mWaitForDebugger = waitForDebugger;
13346                mDebugTransient = !persistent;
13347                if (packageName != null) {
13348                    forceStopPackageLocked(packageName, -1, false, false, true, true,
13349                            false, UserHandle.USER_ALL, "set debug app");
13350                }
13351            }
13352        } finally {
13353            Binder.restoreCallingIdentity(ident);
13354        }
13355    }
13356
13357    /**
13358     * Set or remove an agent to be run whenever an app with the given process name starts.
13359     *
13360     * This method will not check whether the given process name matches a debuggable app. That
13361     * would require scanning all current packages, and a rescan when new packages are installed
13362     * or updated.
13363     *
13364     * Instead, do the check when an application is started and matched to a stored agent.
13365     *
13366     * @param packageName the process name of the app.
13367     * @param agent the agent string to be used, or null to remove any previously set agent.
13368     */
13369    @Override
13370    public void setAgentApp(@NonNull String packageName, @Nullable String agent) {
13371        synchronized (this) {
13372            // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13373            // its own permission.
13374            if (checkCallingPermission(
13375                    android.Manifest.permission.SET_ACTIVITY_WATCHER) !=
13376                        PackageManager.PERMISSION_GRANTED) {
13377                throw new SecurityException(
13378                        "Requires permission " + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13379            }
13380
13381            if (agent == null) {
13382                if (mAppAgentMap != null) {
13383                    mAppAgentMap.remove(packageName);
13384                    if (mAppAgentMap.isEmpty()) {
13385                        mAppAgentMap = null;
13386                    }
13387                }
13388            } else {
13389                if (mAppAgentMap == null) {
13390                    mAppAgentMap = new HashMap<>();
13391                }
13392                if (mAppAgentMap.size() >= 100) {
13393                    // Limit the size of the map, to avoid OOMEs.
13394                    Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName
13395                            + "/" + agent);
13396                    return;
13397                }
13398                mAppAgentMap.put(packageName, agent);
13399            }
13400        }
13401    }
13402
13403    void setTrackAllocationApp(ApplicationInfo app, String processName) {
13404        synchronized (this) {
13405            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13406            if (!isDebuggable) {
13407                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13408                    throw new SecurityException("Process not debuggable: " + app.packageName);
13409                }
13410            }
13411
13412            mTrackAllocationApp = processName;
13413        }
13414    }
13415
13416    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
13417        synchronized (this) {
13418            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13419            if (!isDebuggable) {
13420                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13421                    throw new SecurityException("Process not debuggable: " + app.packageName);
13422                }
13423            }
13424            mProfileApp = processName;
13425
13426            if (mProfilerInfo != null) {
13427                if (mProfilerInfo.profileFd != null) {
13428                    try {
13429                        mProfilerInfo.profileFd.close();
13430                    } catch (IOException e) {
13431                    }
13432                }
13433            }
13434            mProfilerInfo = new ProfilerInfo(profilerInfo);
13435            mProfileType = 0;
13436        }
13437    }
13438
13439    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
13440        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13441        if (!isDebuggable) {
13442            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13443                throw new SecurityException("Process not debuggable: " + app.packageName);
13444            }
13445        }
13446        mNativeDebuggingApp = processName;
13447    }
13448
13449    @Override
13450    public void setAlwaysFinish(boolean enabled) {
13451        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
13452                "setAlwaysFinish()");
13453
13454        long ident = Binder.clearCallingIdentity();
13455        try {
13456            Settings.Global.putInt(
13457                    mContext.getContentResolver(),
13458                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
13459
13460            synchronized (this) {
13461                mAlwaysFinishActivities = enabled;
13462            }
13463        } finally {
13464            Binder.restoreCallingIdentity(ident);
13465        }
13466    }
13467
13468    @Override
13469    public void setActivityController(IActivityController controller, boolean imAMonkey) {
13470        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13471                "setActivityController()");
13472        synchronized (this) {
13473            mController = controller;
13474            mControllerIsAMonkey = imAMonkey;
13475            Watchdog.getInstance().setActivityController(controller);
13476        }
13477    }
13478
13479    @Override
13480    public void setUserIsMonkey(boolean userIsMonkey) {
13481        synchronized (this) {
13482            synchronized (mPidsSelfLocked) {
13483                final int callingPid = Binder.getCallingPid();
13484                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
13485                if (proc == null) {
13486                    throw new SecurityException("Unknown process: " + callingPid);
13487                }
13488                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
13489                    throw new SecurityException("Only an instrumentation process "
13490                            + "with a UiAutomation can call setUserIsMonkey");
13491                }
13492            }
13493            mUserIsMonkey = userIsMonkey;
13494        }
13495    }
13496
13497    @Override
13498    public boolean isUserAMonkey() {
13499        synchronized (this) {
13500            // If there is a controller also implies the user is a monkey.
13501            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
13502        }
13503    }
13504
13505    /**
13506     * @deprecated This method is only used by a few internal components and it will soon be
13507     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13508     * No new code should be calling it.
13509     */
13510    @Deprecated
13511    @Override
13512    public void requestBugReport(int bugreportType) {
13513        String extraOptions = null;
13514        switch (bugreportType) {
13515            case ActivityManager.BUGREPORT_OPTION_FULL:
13516                // Default options.
13517                break;
13518            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
13519                extraOptions = "bugreportplus";
13520                break;
13521            case ActivityManager.BUGREPORT_OPTION_REMOTE:
13522                extraOptions = "bugreportremote";
13523                break;
13524            case ActivityManager.BUGREPORT_OPTION_WEAR:
13525                extraOptions = "bugreportwear";
13526                break;
13527            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
13528                extraOptions = "bugreporttelephony";
13529                break;
13530            case ActivityManager.BUGREPORT_OPTION_WIFI:
13531                extraOptions = "bugreportwifi";
13532                break;
13533            default:
13534                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
13535                        + bugreportType);
13536        }
13537        // Always log caller, even if it does not have permission to dump.
13538        String type = extraOptions == null ? "bugreport" : extraOptions;
13539        Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
13540
13541        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13542        if (extraOptions != null) {
13543            SystemProperties.set("dumpstate.options", extraOptions);
13544        }
13545        SystemProperties.set("ctl.start", "bugreport");
13546    }
13547
13548    /**
13549     * @deprecated This method is only used by a few internal components and it will soon be
13550     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13551     * No new code should be calling it.
13552     */
13553    @Deprecated
13554    private void requestBugReportWithDescription(String shareTitle, String shareDescription,
13555                                                 int bugreportType) {
13556        if (!TextUtils.isEmpty(shareTitle)) {
13557            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13558                String errorStr = "shareTitle should be less than " +
13559                        MAX_BUGREPORT_TITLE_SIZE + " characters";
13560                throw new IllegalArgumentException(errorStr);
13561            } else {
13562                if (!TextUtils.isEmpty(shareDescription)) {
13563                    int length;
13564                    try {
13565                        length = shareDescription.getBytes("UTF-8").length;
13566                    } catch (UnsupportedEncodingException e) {
13567                        String errorStr = "shareDescription: UnsupportedEncodingException";
13568                        throw new IllegalArgumentException(errorStr);
13569                    }
13570                    if (length > SystemProperties.PROP_VALUE_MAX) {
13571                        String errorStr = "shareTitle should be less than " +
13572                                SystemProperties.PROP_VALUE_MAX + " bytes";
13573                        throw new IllegalArgumentException(errorStr);
13574                    } else {
13575                        SystemProperties.set("dumpstate.options.description", shareDescription);
13576                    }
13577                }
13578                SystemProperties.set("dumpstate.options.title", shareTitle);
13579            }
13580        }
13581
13582        Slog.d(TAG, "Bugreport notification title " + shareTitle
13583                + " description " + shareDescription);
13584        requestBugReport(bugreportType);
13585    }
13586
13587    /**
13588     * @deprecated This method is only used by a few internal components and it will soon be
13589     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13590     * No new code should be calling it.
13591     */
13592    @Deprecated
13593    @Override
13594    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13595        requestBugReportWithDescription(shareTitle, shareDescription,
13596                ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13597    }
13598
13599    /**
13600     * @deprecated This method is only used by a few internal components and it will soon be
13601     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13602     * No new code should be calling it.
13603     */
13604    @Deprecated
13605    @Override
13606    public void requestWifiBugReport(String shareTitle, String shareDescription) {
13607        requestBugReportWithDescription(shareTitle, shareDescription,
13608                ActivityManager.BUGREPORT_OPTION_WIFI);
13609    }
13610
13611
13612    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13613        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13614    }
13615
13616    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13617        if (r != null && (r.instr != null || r.usingWrapper)) {
13618            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13619        }
13620        return KEY_DISPATCHING_TIMEOUT;
13621    }
13622
13623    @Override
13624    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13625        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13626                != PackageManager.PERMISSION_GRANTED) {
13627            throw new SecurityException("Requires permission "
13628                    + android.Manifest.permission.FILTER_EVENTS);
13629        }
13630        ProcessRecord proc;
13631        long timeout;
13632        synchronized (this) {
13633            synchronized (mPidsSelfLocked) {
13634                proc = mPidsSelfLocked.get(pid);
13635            }
13636            timeout = getInputDispatchingTimeoutLocked(proc);
13637        }
13638
13639        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13640            return -1;
13641        }
13642
13643        return timeout;
13644    }
13645
13646    /**
13647     * Handle input dispatching timeouts.
13648     * Returns whether input dispatching should be aborted or not.
13649     */
13650    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13651            final ActivityRecord activity, final ActivityRecord parent,
13652            final boolean aboveSystem, String reason) {
13653        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13654                != PackageManager.PERMISSION_GRANTED) {
13655            throw new SecurityException("Requires permission "
13656                    + android.Manifest.permission.FILTER_EVENTS);
13657        }
13658
13659        final String annotation;
13660        if (reason == null) {
13661            annotation = "Input dispatching timed out";
13662        } else {
13663            annotation = "Input dispatching timed out (" + reason + ")";
13664        }
13665
13666        if (proc != null) {
13667            synchronized (this) {
13668                if (proc.debugging) {
13669                    return false;
13670                }
13671
13672                if (proc.instr != null) {
13673                    Bundle info = new Bundle();
13674                    info.putString("shortMsg", "keyDispatchingTimedOut");
13675                    info.putString("longMsg", annotation);
13676                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13677                    return true;
13678                }
13679            }
13680            mHandler.post(new Runnable() {
13681                @Override
13682                public void run() {
13683                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13684                }
13685            });
13686        }
13687
13688        return true;
13689    }
13690
13691    @Override
13692    public Bundle getAssistContextExtras(int requestType) {
13693        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13694                null, null, true /* focused */, true /* newSessionId */,
13695                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13696        if (pae == null) {
13697            return null;
13698        }
13699        synchronized (pae) {
13700            while (!pae.haveResult) {
13701                try {
13702                    pae.wait();
13703                } catch (InterruptedException e) {
13704                }
13705            }
13706        }
13707        synchronized (this) {
13708            buildAssistBundleLocked(pae, pae.result);
13709            mPendingAssistExtras.remove(pae);
13710            mUiHandler.removeCallbacks(pae);
13711        }
13712        return pae.extras;
13713    }
13714
13715    @Override
13716    public boolean isAssistDataAllowedOnCurrentActivity() {
13717        int userId;
13718        synchronized (this) {
13719            final ActivityStack focusedStack = getFocusedStack();
13720            if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
13721                return false;
13722            }
13723
13724            final ActivityRecord activity = focusedStack.getTopActivity();
13725            if (activity == null) {
13726                return false;
13727            }
13728            userId = activity.userId;
13729        }
13730        return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
13731    }
13732
13733    @Override
13734    public boolean showAssistFromActivity(IBinder token, Bundle args) {
13735        long ident = Binder.clearCallingIdentity();
13736        try {
13737            synchronized (this) {
13738                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13739                ActivityRecord top = getFocusedStack().getTopActivity();
13740                if (top != caller) {
13741                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13742                            + " is not current top " + top);
13743                    return false;
13744                }
13745                if (!top.nowVisible) {
13746                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13747                            + " is not visible");
13748                    return false;
13749                }
13750            }
13751            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13752                    token);
13753        } finally {
13754            Binder.restoreCallingIdentity(ident);
13755        }
13756    }
13757
13758    @Override
13759    public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
13760            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13761        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13762                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13763                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13764    }
13765
13766    @Override
13767    public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
13768            IBinder activityToken, int flags) {
13769        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13770                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13771                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13772    }
13773
13774    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13775            IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13776            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13777            int flags) {
13778        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13779                "enqueueAssistContext()");
13780
13781        synchronized (this) {
13782            ActivityRecord activity = getFocusedStack().getTopActivity();
13783            if (activity == null) {
13784                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13785                return null;
13786            }
13787            if (activity.app == null || activity.app.thread == null) {
13788                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13789                return null;
13790            }
13791            if (focused) {
13792                if (activityToken != null) {
13793                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13794                    if (activity != caller) {
13795                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13796                                + " is not current top " + activity);
13797                        return null;
13798                    }
13799                }
13800            } else {
13801                activity = ActivityRecord.forTokenLocked(activityToken);
13802                if (activity == null) {
13803                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13804                            + " couldn't be found");
13805                    return null;
13806                }
13807                if (activity.app == null || activity.app.thread == null) {
13808                    Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13809                    return null;
13810                }
13811            }
13812
13813            PendingAssistExtras pae;
13814            Bundle extras = new Bundle();
13815            if (args != null) {
13816                extras.putAll(args);
13817            }
13818            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13819            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13820
13821            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13822                    userHandle);
13823            pae.isHome = activity.isActivityTypeHome();
13824
13825            // Increment the sessionId if necessary
13826            if (newSessionId) {
13827                mViSessionId++;
13828            }
13829            try {
13830                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13831                        mViSessionId, flags);
13832                mPendingAssistExtras.add(pae);
13833                mUiHandler.postDelayed(pae, timeout);
13834            } catch (RemoteException e) {
13835                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13836                return null;
13837            }
13838            return pae;
13839        }
13840    }
13841
13842    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13843        IAssistDataReceiver receiver;
13844        synchronized (this) {
13845            mPendingAssistExtras.remove(pae);
13846            receiver = pae.receiver;
13847        }
13848        if (receiver != null) {
13849            // Caller wants result sent back to them.
13850            Bundle sendBundle = new Bundle();
13851            // At least return the receiver extras
13852            sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13853            try {
13854                pae.receiver.onHandleAssistData(sendBundle);
13855            } catch (RemoteException e) {
13856            }
13857        }
13858    }
13859
13860    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13861        if (result != null) {
13862            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13863        }
13864        if (pae.hint != null) {
13865            pae.extras.putBoolean(pae.hint, true);
13866        }
13867    }
13868
13869    /** Called from an app when assist data is ready. */
13870    @Override
13871    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13872            AssistContent content, Uri referrer) {
13873        PendingAssistExtras pae = (PendingAssistExtras)token;
13874        synchronized (pae) {
13875            pae.result = extras;
13876            pae.structure = structure;
13877            pae.content = content;
13878            if (referrer != null) {
13879                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13880            }
13881            if (structure != null) {
13882                structure.setHomeActivity(pae.isHome);
13883            }
13884            pae.haveResult = true;
13885            pae.notifyAll();
13886            if (pae.intent == null && pae.receiver == null) {
13887                // Caller is just waiting for the result.
13888                return;
13889            }
13890        }
13891        // We are now ready to launch the assist activity.
13892        IAssistDataReceiver sendReceiver = null;
13893        Bundle sendBundle = null;
13894        synchronized (this) {
13895            buildAssistBundleLocked(pae, extras);
13896            boolean exists = mPendingAssistExtras.remove(pae);
13897            mUiHandler.removeCallbacks(pae);
13898            if (!exists) {
13899                // Timed out.
13900                return;
13901            }
13902
13903            if ((sendReceiver=pae.receiver) != null) {
13904                // Caller wants result sent back to them.
13905                sendBundle = new Bundle();
13906                sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
13907                sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
13908                sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
13909                sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13910            }
13911        }
13912        if (sendReceiver != null) {
13913            try {
13914                sendReceiver.onHandleAssistData(sendBundle);
13915            } catch (RemoteException e) {
13916            }
13917            return;
13918        }
13919
13920        final long ident = Binder.clearCallingIdentity();
13921        try {
13922            if (TextUtils.equals(pae.intent.getAction(),
13923                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13924                pae.intent.putExtras(pae.extras);
13925                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13926            } else {
13927                pae.intent.replaceExtras(pae.extras);
13928                pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
13929                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
13930                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13931                closeSystemDialogs("assist");
13932
13933                try {
13934                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13935                } catch (ActivityNotFoundException e) {
13936                    Slog.w(TAG, "No activity to handle assist action.", e);
13937                }
13938            }
13939        } finally {
13940            Binder.restoreCallingIdentity(ident);
13941        }
13942    }
13943
13944    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13945            Bundle args) {
13946        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13947                true /* focused */, true /* newSessionId */, userHandle, args,
13948                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13949    }
13950
13951    public void registerProcessObserver(IProcessObserver observer) {
13952        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13953                "registerProcessObserver()");
13954        synchronized (this) {
13955            mProcessObservers.register(observer);
13956        }
13957    }
13958
13959    @Override
13960    public void unregisterProcessObserver(IProcessObserver observer) {
13961        synchronized (this) {
13962            mProcessObservers.unregister(observer);
13963        }
13964    }
13965
13966    @Override
13967    public int getUidProcessState(int uid, String callingPackage) {
13968        if (!hasUsageStatsPermission(callingPackage)) {
13969            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13970                    "getUidProcessState");
13971        }
13972
13973        synchronized (this) {
13974            UidRecord uidRec = mActiveUids.get(uid);
13975            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13976        }
13977    }
13978
13979    @Override
13980    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13981            String callingPackage) {
13982        if (!hasUsageStatsPermission(callingPackage)) {
13983            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13984                    "registerUidObserver");
13985        }
13986        synchronized (this) {
13987            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13988                    callingPackage, which, cutpoint));
13989        }
13990    }
13991
13992    @Override
13993    public void unregisterUidObserver(IUidObserver observer) {
13994        synchronized (this) {
13995            mUidObservers.unregister(observer);
13996        }
13997    }
13998
13999    @Override
14000    public boolean convertFromTranslucent(IBinder token) {
14001        final long origId = Binder.clearCallingIdentity();
14002        try {
14003            synchronized (this) {
14004                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14005                if (r == null) {
14006                    return false;
14007                }
14008                final boolean translucentChanged = r.changeWindowTranslucency(true);
14009                if (translucentChanged) {
14010                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14011                }
14012                mWindowManager.setAppFullscreen(token, true);
14013                return translucentChanged;
14014            }
14015        } finally {
14016            Binder.restoreCallingIdentity(origId);
14017        }
14018    }
14019
14020    @Override
14021    public boolean convertToTranslucent(IBinder token, Bundle options) {
14022        SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
14023        final long origId = Binder.clearCallingIdentity();
14024        try {
14025            synchronized (this) {
14026                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14027                if (r == null) {
14028                    return false;
14029                }
14030                final TaskRecord task = r.getTask();
14031                int index = task.mActivities.lastIndexOf(r);
14032                if (index > 0) {
14033                    ActivityRecord under = task.mActivities.get(index - 1);
14034                    under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
14035                }
14036                final boolean translucentChanged = r.changeWindowTranslucency(false);
14037                if (translucentChanged) {
14038                    r.getStack().convertActivityToTranslucent(r);
14039                }
14040                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14041                mWindowManager.setAppFullscreen(token, false);
14042                return translucentChanged;
14043            }
14044        } finally {
14045            Binder.restoreCallingIdentity(origId);
14046        }
14047    }
14048
14049    @Override
14050    public Bundle getActivityOptions(IBinder token) {
14051        final long origId = Binder.clearCallingIdentity();
14052        try {
14053            synchronized (this) {
14054                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14055                if (r != null) {
14056                    final ActivityOptions activityOptions = r.takeOptionsLocked();
14057                    return activityOptions == null ? null : activityOptions.toBundle();
14058                }
14059                return null;
14060            }
14061        } finally {
14062            Binder.restoreCallingIdentity(origId);
14063        }
14064    }
14065
14066    @Override
14067    public void setImmersive(IBinder token, boolean immersive) {
14068        synchronized(this) {
14069            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14070            if (r == null) {
14071                throw new IllegalArgumentException();
14072            }
14073            r.immersive = immersive;
14074
14075            // update associated state if we're frontmost
14076            if (r == mStackSupervisor.getResumedActivityLocked()) {
14077                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
14078                applyUpdateLockStateLocked(r);
14079            }
14080        }
14081    }
14082
14083    @Override
14084    public boolean isImmersive(IBinder token) {
14085        synchronized (this) {
14086            ActivityRecord r = ActivityRecord.isInStackLocked(token);
14087            if (r == null) {
14088                throw new IllegalArgumentException();
14089            }
14090            return r.immersive;
14091        }
14092    }
14093
14094    @Override
14095    public void setVrThread(int tid) {
14096        enforceSystemHasVrFeature();
14097        synchronized (this) {
14098            synchronized (mPidsSelfLocked) {
14099                final int pid = Binder.getCallingPid();
14100                final ProcessRecord proc = mPidsSelfLocked.get(pid);
14101                mVrController.setVrThreadLocked(tid, pid, proc);
14102            }
14103        }
14104    }
14105
14106    @Override
14107    public void setPersistentVrThread(int tid) {
14108        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
14109            final String msg = "Permission Denial: setPersistentVrThread() from pid="
14110                    + Binder.getCallingPid()
14111                    + ", uid=" + Binder.getCallingUid()
14112                    + " requires " + permission.RESTRICTED_VR_ACCESS;
14113            Slog.w(TAG, msg);
14114            throw new SecurityException(msg);
14115        }
14116        enforceSystemHasVrFeature();
14117        synchronized (this) {
14118            synchronized (mPidsSelfLocked) {
14119                final int pid = Binder.getCallingPid();
14120                final ProcessRecord proc = mPidsSelfLocked.get(pid);
14121                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
14122            }
14123        }
14124    }
14125
14126    /**
14127     * Schedule the given thread a normal scheduling priority.
14128     *
14129     * @param tid the tid of the thread to adjust the scheduling of.
14130     * @param suppressLogs {@code true} if any error logging should be disabled.
14131     *
14132     * @return {@code true} if this succeeded.
14133     */
14134    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
14135        try {
14136            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
14137            return true;
14138        } catch (IllegalArgumentException e) {
14139            if (!suppressLogs) {
14140                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14141            }
14142        } catch (SecurityException e) {
14143            if (!suppressLogs) {
14144                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14145            }
14146        }
14147        return false;
14148    }
14149
14150    /**
14151     * Schedule the given thread an FIFO scheduling priority.
14152     *
14153     * @param tid the tid of the thread to adjust the scheduling of.
14154     * @param suppressLogs {@code true} if any error logging should be disabled.
14155     *
14156     * @return {@code true} if this succeeded.
14157     */
14158    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
14159        try {
14160            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
14161            return true;
14162        } catch (IllegalArgumentException e) {
14163            if (!suppressLogs) {
14164                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14165            }
14166        } catch (SecurityException e) {
14167            if (!suppressLogs) {
14168                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14169            }
14170        }
14171        return false;
14172    }
14173
14174    /**
14175     * Check that we have the features required for VR-related API calls, and throw an exception if
14176     * not.
14177     */
14178    private void enforceSystemHasVrFeature() {
14179        if (!mContext.getPackageManager().hasSystemFeature(
14180                PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
14181            throw new UnsupportedOperationException("VR mode not supported on this device!");
14182        }
14183    }
14184
14185    @Override
14186    public void setRenderThread(int tid) {
14187        synchronized (this) {
14188            ProcessRecord proc;
14189            int pid = Binder.getCallingPid();
14190            if (pid == Process.myPid()) {
14191                demoteSystemServerRenderThread(tid);
14192                return;
14193            }
14194            synchronized (mPidsSelfLocked) {
14195                proc = mPidsSelfLocked.get(pid);
14196                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
14197                    // ensure the tid belongs to the process
14198                    if (!isThreadInProcess(pid, tid)) {
14199                        throw new IllegalArgumentException(
14200                            "Render thread does not belong to process");
14201                    }
14202                    proc.renderThreadTid = tid;
14203                    if (DEBUG_OOM_ADJ) {
14204                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
14205                    }
14206                    // promote to FIFO now
14207                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
14208                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
14209                        if (mUseFifoUiScheduling) {
14210                            setThreadScheduler(proc.renderThreadTid,
14211                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
14212                        } else {
14213                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
14214                        }
14215                    }
14216                } else {
14217                    if (DEBUG_OOM_ADJ) {
14218                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
14219                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
14220                               mUseFifoUiScheduling);
14221                    }
14222                }
14223            }
14224        }
14225    }
14226
14227    /**
14228     * We only use RenderThread in system_server to store task snapshots to the disk, which should
14229     * happen in the background. Thus, demote render thread from system_server to a lower priority.
14230     *
14231     * @param tid the tid of the RenderThread
14232     */
14233    private void demoteSystemServerRenderThread(int tid) {
14234        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
14235    }
14236
14237    @Override
14238    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
14239        enforceSystemHasVrFeature();
14240
14241        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14242
14243        ActivityRecord r;
14244        synchronized (this) {
14245            r = ActivityRecord.isInStackLocked(token);
14246        }
14247
14248        if (r == null) {
14249            throw new IllegalArgumentException();
14250        }
14251
14252        int err;
14253        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
14254                VrManagerInternal.NO_ERROR) {
14255            return err;
14256        }
14257
14258        synchronized(this) {
14259            r.requestedVrComponent = (enabled) ? packageName : null;
14260
14261            // Update associated state if this activity is currently focused
14262            if (r == mStackSupervisor.getResumedActivityLocked()) {
14263                applyUpdateVrModeLocked(r);
14264            }
14265            return 0;
14266        }
14267    }
14268
14269    @Override
14270    public boolean isVrModePackageEnabled(ComponentName packageName) {
14271        enforceSystemHasVrFeature();
14272
14273        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14274
14275        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
14276                VrManagerInternal.NO_ERROR;
14277    }
14278
14279    public boolean isTopActivityImmersive() {
14280        enforceNotIsolatedCaller("startActivity");
14281        synchronized (this) {
14282            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
14283            return (r != null) ? r.immersive : false;
14284        }
14285    }
14286
14287    /**
14288     * @return whether the system should disable UI modes incompatible with VR mode.
14289     */
14290    boolean shouldDisableNonVrUiLocked() {
14291        return mVrController.shouldDisableNonVrUiLocked();
14292    }
14293
14294    @Override
14295    public boolean isTopOfTask(IBinder token) {
14296        synchronized (this) {
14297            ActivityRecord r = ActivityRecord.isInStackLocked(token);
14298            if (r == null) {
14299                throw new IllegalArgumentException();
14300            }
14301            return r.getTask().getTopActivity() == r;
14302        }
14303    }
14304
14305    @Override
14306    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
14307        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
14308            String msg = "Permission Denial: setHasTopUi() from pid="
14309                    + Binder.getCallingPid()
14310                    + ", uid=" + Binder.getCallingUid()
14311                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
14312            Slog.w(TAG, msg);
14313            throw new SecurityException(msg);
14314        }
14315        final int pid = Binder.getCallingPid();
14316        final long origId = Binder.clearCallingIdentity();
14317        try {
14318            synchronized (this) {
14319                boolean changed = false;
14320                ProcessRecord pr;
14321                synchronized (mPidsSelfLocked) {
14322                    pr = mPidsSelfLocked.get(pid);
14323                    if (pr == null) {
14324                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
14325                        return;
14326                    }
14327                    if (pr.hasTopUi != hasTopUi) {
14328                        if (DEBUG_OOM_ADJ) {
14329                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
14330                        }
14331                        pr.hasTopUi = hasTopUi;
14332                        changed = true;
14333                    }
14334                }
14335                if (changed) {
14336                    updateOomAdjLocked(pr, true);
14337                }
14338            }
14339        } finally {
14340            Binder.restoreCallingIdentity(origId);
14341        }
14342    }
14343
14344    void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
14345        synchronized (ActivityManagerService.this) {
14346            final ProcessRecord pr;
14347            synchronized (mPidsSelfLocked) {
14348                pr = mPidsSelfLocked.get(pid);
14349                if (pr == null) {
14350                    Slog.w(TAG, "setRunningRemoteAnimation called on unknown pid: " + pid);
14351                    return;
14352                }
14353            }
14354            if (pr.runningRemoteAnimation == runningRemoteAnimation) {
14355                return;
14356            }
14357            pr.runningRemoteAnimation = runningRemoteAnimation;
14358            if (DEBUG_OOM_ADJ) {
14359                Slog.i(TAG, "Setting runningRemoteAnimation=" + pr.runningRemoteAnimation
14360                        + " for pid=" + pid);
14361            }
14362            updateOomAdjLocked(pr, true);
14363        }
14364    }
14365
14366    public final void enterSafeMode() {
14367        synchronized(this) {
14368            // It only makes sense to do this before the system is ready
14369            // and started launching other packages.
14370            if (!mSystemReady) {
14371                try {
14372                    AppGlobals.getPackageManager().enterSafeMode();
14373                } catch (RemoteException e) {
14374                }
14375            }
14376
14377            mSafeMode = true;
14378        }
14379    }
14380
14381    public final void showSafeModeOverlay() {
14382        View v = LayoutInflater.from(mContext).inflate(
14383                com.android.internal.R.layout.safe_mode, null);
14384        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
14385        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
14386        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
14387        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
14388        lp.gravity = Gravity.BOTTOM | Gravity.START;
14389        lp.format = v.getBackground().getOpacity();
14390        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
14391                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
14392        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
14393        ((WindowManager)mContext.getSystemService(
14394                Context.WINDOW_SERVICE)).addView(v, lp);
14395    }
14396
14397    @Override
14398    public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
14399            String sourcePkg, String tag) {
14400        if (workSource != null && workSource.isEmpty()) {
14401            workSource = null;
14402        }
14403
14404        if (sourceUid <= 0 && workSource == null) {
14405            // Try and derive a UID to attribute things to based on the caller.
14406            if (sender != null) {
14407                if (!(sender instanceof PendingIntentRecord)) {
14408                    return;
14409                }
14410
14411                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14412                final int callerUid = Binder.getCallingUid();
14413                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14414            } else {
14415                // TODO(narayan): Should we throw an exception in this case ? It means that we
14416                // haven't been able to derive a UID to attribute things to.
14417                return;
14418            }
14419        }
14420
14421        if (DEBUG_POWER) {
14422            Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
14423                    + ", workSource=" + workSource + ", tag=" + tag + "]");
14424        }
14425
14426        mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
14427    }
14428
14429    @Override
14430    public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
14431            String tag) {
14432        if (workSource != null && workSource.isEmpty()) {
14433            workSource = null;
14434        }
14435
14436        if (sourceUid <= 0 && workSource == null) {
14437            // Try and derive a UID to attribute things to based on the caller.
14438            if (sender != null) {
14439                if (!(sender instanceof PendingIntentRecord)) {
14440                    return;
14441                }
14442
14443                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14444                final int callerUid = Binder.getCallingUid();
14445                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14446            } else {
14447                // TODO(narayan): Should we throw an exception in this case ? It means that we
14448                // haven't been able to derive a UID to attribute things to.
14449                return;
14450            }
14451        }
14452
14453        if (DEBUG_POWER) {
14454            Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
14455                    ", tag=" + tag + "]");
14456        }
14457
14458        mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
14459    }
14460
14461    @Override
14462    public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
14463            String tag) {
14464        if (workSource != null && workSource.isEmpty()) {
14465            workSource = null;
14466        }
14467
14468        if (sourceUid <= 0 && workSource == null) {
14469            // Try and derive a UID to attribute things to based on the caller.
14470            if (sender != null) {
14471                if (!(sender instanceof PendingIntentRecord)) {
14472                    return;
14473                }
14474
14475                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14476                final int callerUid = Binder.getCallingUid();
14477                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14478            } else {
14479                // TODO(narayan): Should we throw an exception in this case ? It means that we
14480                // haven't been able to derive a UID to attribute things to.
14481                return;
14482            }
14483        }
14484
14485        if (DEBUG_POWER) {
14486            Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
14487                    ", tag=" + tag + "]");
14488        }
14489
14490        mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
14491    }
14492
14493    public boolean killPids(int[] pids, String pReason, boolean secure) {
14494        if (Binder.getCallingUid() != SYSTEM_UID) {
14495            throw new SecurityException("killPids only available to the system");
14496        }
14497        String reason = (pReason == null) ? "Unknown" : pReason;
14498        // XXX Note: don't acquire main activity lock here, because the window
14499        // manager calls in with its locks held.
14500
14501        boolean killed = false;
14502        synchronized (mPidsSelfLocked) {
14503            int worstType = 0;
14504            for (int i=0; i<pids.length; i++) {
14505                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14506                if (proc != null) {
14507                    int type = proc.setAdj;
14508                    if (type > worstType) {
14509                        worstType = type;
14510                    }
14511                }
14512            }
14513
14514            // If the worst oom_adj is somewhere in the cached proc LRU range,
14515            // then constrain it so we will kill all cached procs.
14516            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
14517                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
14518                worstType = ProcessList.CACHED_APP_MIN_ADJ;
14519            }
14520
14521            // If this is not a secure call, don't let it kill processes that
14522            // are important.
14523            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
14524                worstType = ProcessList.SERVICE_ADJ;
14525            }
14526
14527            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
14528            for (int i=0; i<pids.length; i++) {
14529                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14530                if (proc == null) {
14531                    continue;
14532                }
14533                int adj = proc.setAdj;
14534                if (adj >= worstType && !proc.killedByAm) {
14535                    proc.kill(reason, true);
14536                    killed = true;
14537                }
14538            }
14539        }
14540        return killed;
14541    }
14542
14543    @Override
14544    public void killUid(int appId, int userId, String reason) {
14545        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
14546        synchronized (this) {
14547            final long identity = Binder.clearCallingIdentity();
14548            try {
14549                killPackageProcessesLocked(null, appId, userId,
14550                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
14551                        reason != null ? reason : "kill uid");
14552            } finally {
14553                Binder.restoreCallingIdentity(identity);
14554            }
14555        }
14556    }
14557
14558    @Override
14559    public boolean killProcessesBelowForeground(String reason) {
14560        if (Binder.getCallingUid() != SYSTEM_UID) {
14561            throw new SecurityException("killProcessesBelowForeground() only available to system");
14562        }
14563
14564        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
14565    }
14566
14567    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
14568        if (Binder.getCallingUid() != SYSTEM_UID) {
14569            throw new SecurityException("killProcessesBelowAdj() only available to system");
14570        }
14571
14572        boolean killed = false;
14573        synchronized (mPidsSelfLocked) {
14574            final int size = mPidsSelfLocked.size();
14575            for (int i = 0; i < size; i++) {
14576                final int pid = mPidsSelfLocked.keyAt(i);
14577                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14578                if (proc == null) continue;
14579
14580                final int adj = proc.setAdj;
14581                if (adj > belowAdj && !proc.killedByAm) {
14582                    proc.kill(reason, true);
14583                    killed = true;
14584                }
14585            }
14586        }
14587        return killed;
14588    }
14589
14590    @Override
14591    public void hang(final IBinder who, boolean allowRestart) {
14592        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14593                != PackageManager.PERMISSION_GRANTED) {
14594            throw new SecurityException("Requires permission "
14595                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14596        }
14597
14598        final IBinder.DeathRecipient death = new DeathRecipient() {
14599            @Override
14600            public void binderDied() {
14601                synchronized (this) {
14602                    notifyAll();
14603                }
14604            }
14605        };
14606
14607        try {
14608            who.linkToDeath(death, 0);
14609        } catch (RemoteException e) {
14610            Slog.w(TAG, "hang: given caller IBinder is already dead.");
14611            return;
14612        }
14613
14614        synchronized (this) {
14615            Watchdog.getInstance().setAllowRestart(allowRestart);
14616            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
14617            synchronized (death) {
14618                while (who.isBinderAlive()) {
14619                    try {
14620                        death.wait();
14621                    } catch (InterruptedException e) {
14622                    }
14623                }
14624            }
14625            Watchdog.getInstance().setAllowRestart(true);
14626        }
14627    }
14628
14629    @Override
14630    public void restart() {
14631        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14632                != PackageManager.PERMISSION_GRANTED) {
14633            throw new SecurityException("Requires permission "
14634                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14635        }
14636
14637        Log.i(TAG, "Sending shutdown broadcast...");
14638
14639        BroadcastReceiver br = new BroadcastReceiver() {
14640            @Override public void onReceive(Context context, Intent intent) {
14641                // Now the broadcast is done, finish up the low-level shutdown.
14642                Log.i(TAG, "Shutting down activity manager...");
14643                shutdown(10000);
14644                Log.i(TAG, "Shutdown complete, restarting!");
14645                killProcess(myPid());
14646                System.exit(10);
14647            }
14648        };
14649
14650        // First send the high-level shut down broadcast.
14651        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14652        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14653        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
14654        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
14655        mContext.sendOrderedBroadcastAsUser(intent,
14656                UserHandle.ALL, null, br, mHandler, 0, null, null);
14657        */
14658        br.onReceive(mContext, intent);
14659    }
14660
14661    private long getLowRamTimeSinceIdle(long now) {
14662        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
14663    }
14664
14665    @Override
14666    public void performIdleMaintenance() {
14667        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14668                != PackageManager.PERMISSION_GRANTED) {
14669            throw new SecurityException("Requires permission "
14670                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14671        }
14672
14673        synchronized (this) {
14674            final long now = SystemClock.uptimeMillis();
14675            final long timeSinceLastIdle = now - mLastIdleTime;
14676            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
14677            mLastIdleTime = now;
14678            mLowRamTimeSinceLastIdle = 0;
14679            if (mLowRamStartTime != 0) {
14680                mLowRamStartTime = now;
14681            }
14682
14683            StringBuilder sb = new StringBuilder(128);
14684            sb.append("Idle maintenance over ");
14685            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14686            sb.append(" low RAM for ");
14687            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14688            Slog.i(TAG, sb.toString());
14689
14690            // If at least 1/3 of our time since the last idle period has been spent
14691            // with RAM low, then we want to kill processes.
14692            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14693
14694            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14695                ProcessRecord proc = mLruProcesses.get(i);
14696                if (proc.notCachedSinceIdle) {
14697                    if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
14698                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14699                        if (doKilling && proc.initialIdlePss != 0
14700                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14701                            sb = new StringBuilder(128);
14702                            sb.append("Kill");
14703                            sb.append(proc.processName);
14704                            sb.append(" in idle maint: pss=");
14705                            sb.append(proc.lastPss);
14706                            sb.append(", swapPss=");
14707                            sb.append(proc.lastSwapPss);
14708                            sb.append(", initialPss=");
14709                            sb.append(proc.initialIdlePss);
14710                            sb.append(", period=");
14711                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14712                            sb.append(", lowRamPeriod=");
14713                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14714                            Slog.wtfQuiet(TAG, sb.toString());
14715                            proc.kill("idle maint (pss " + proc.lastPss
14716                                    + " from " + proc.initialIdlePss + ")", true);
14717                        }
14718                    }
14719                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14720                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14721                    proc.notCachedSinceIdle = true;
14722                    proc.initialIdlePss = 0;
14723                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null,
14724                            mTestPssMode, isSleepingLocked(), now);
14725                }
14726            }
14727        }
14728    }
14729
14730    @Override
14731    public void sendIdleJobTrigger() {
14732        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14733                != PackageManager.PERMISSION_GRANTED) {
14734            throw new SecurityException("Requires permission "
14735                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14736        }
14737
14738        final long ident = Binder.clearCallingIdentity();
14739        try {
14740            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14741                    .setPackage("android")
14742                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14743            broadcastIntent(null, intent, null, null, 0, null, null, null,
14744                    OP_NONE, null, true, false, UserHandle.USER_ALL);
14745        } finally {
14746            Binder.restoreCallingIdentity(ident);
14747        }
14748    }
14749
14750    private void retrieveSettings() {
14751        final ContentResolver resolver = mContext.getContentResolver();
14752        final boolean freeformWindowManagement =
14753                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14754                        || Settings.Global.getInt(
14755                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14756
14757        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14758        final boolean supportsPictureInPicture = supportsMultiWindow &&
14759                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14760        final boolean supportsSplitScreenMultiWindow =
14761                ActivityManager.supportsSplitScreenMultiWindow(mContext);
14762        final boolean supportsMultiDisplay = mContext.getPackageManager()
14763                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14764        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14765        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14766        final boolean alwaysFinishActivities =
14767                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14768        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14769        final boolean forceResizable = Settings.Global.getInt(
14770                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14771        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14772                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14773        final boolean supportsLeanbackOnly =
14774                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14775        mHiddenApiBlacklist.registerObserver();
14776
14777        // Transfer any global setting for forcing RTL layout, into a System Property
14778        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14779
14780        final Configuration configuration = new Configuration();
14781        Settings.System.getConfiguration(resolver, configuration);
14782        if (forceRtl) {
14783            // This will take care of setting the correct layout direction flags
14784            configuration.setLayoutDirection(configuration.locale);
14785        }
14786
14787        synchronized (this) {
14788            mDebugApp = mOrigDebugApp = debugApp;
14789            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14790            mAlwaysFinishActivities = alwaysFinishActivities;
14791            mSupportsLeanbackOnly = supportsLeanbackOnly;
14792            mForceResizableActivities = forceResizable;
14793            final boolean multiWindowFormEnabled = freeformWindowManagement
14794                    || supportsSplitScreenMultiWindow
14795                    || supportsPictureInPicture
14796                    || supportsMultiDisplay;
14797            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14798                mSupportsMultiWindow = true;
14799                mSupportsFreeformWindowManagement = freeformWindowManagement;
14800                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14801                mSupportsPictureInPicture = supportsPictureInPicture;
14802                mSupportsMultiDisplay = supportsMultiDisplay;
14803            } else {
14804                mSupportsMultiWindow = false;
14805                mSupportsFreeformWindowManagement = false;
14806                mSupportsSplitScreenMultiWindow = false;
14807                mSupportsPictureInPicture = false;
14808                mSupportsMultiDisplay = false;
14809            }
14810            mWindowManager.setForceResizableTasks(mForceResizableActivities);
14811            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14812            // This happens before any activities are started, so we can change global configuration
14813            // in-place.
14814            updateConfigurationLocked(configuration, null, true);
14815            final Configuration globalConfig = getGlobalConfiguration();
14816            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14817
14818            // Load resources only after the current configuration has been set.
14819            final Resources res = mContext.getResources();
14820            mThumbnailWidth = res.getDimensionPixelSize(
14821                    com.android.internal.R.dimen.thumbnail_width);
14822            mThumbnailHeight = res.getDimensionPixelSize(
14823                    com.android.internal.R.dimen.thumbnail_height);
14824            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14825                    com.android.internal.R.string.config_appsNotReportingCrashes));
14826            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14827                    com.android.internal.R.bool.config_customUserSwitchUi);
14828            mUserController.mMaxRunningUsers = res.getInteger(
14829                    com.android.internal.R.integer.config_multiuserMaxRunningUsers);
14830
14831            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14832                mFullscreenThumbnailScale = (float) res
14833                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14834                    (float) globalConfig.screenWidthDp;
14835            } else {
14836                mFullscreenThumbnailScale = res.getFraction(
14837                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14838            }
14839            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14840        }
14841    }
14842
14843    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14844        traceLog.traceBegin("PhaseActivityManagerReady");
14845        synchronized(this) {
14846            if (mSystemReady) {
14847                // If we're done calling all the receivers, run the next "boot phase" passed in
14848                // by the SystemServer
14849                if (goingCallback != null) {
14850                    goingCallback.run();
14851                }
14852                return;
14853            }
14854
14855            mLocalDeviceIdleController
14856                    = LocalServices.getService(DeviceIdleController.LocalService.class);
14857            mAssistUtils = new AssistUtils(mContext);
14858            mVrController.onSystemReady();
14859            // Make sure we have the current profile info, since it is needed for security checks.
14860            mUserController.onSystemReady();
14861            mRecentTasks.onSystemReadyLocked();
14862            mAppOpsService.systemReady();
14863            mSystemReady = true;
14864        }
14865
14866        try {
14867            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14868                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14869                    .getSerial();
14870        } catch (RemoteException e) {}
14871
14872        ArrayList<ProcessRecord> procsToKill = null;
14873        synchronized(mPidsSelfLocked) {
14874            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14875                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14876                if (!isAllowedWhileBooting(proc.info)){
14877                    if (procsToKill == null) {
14878                        procsToKill = new ArrayList<ProcessRecord>();
14879                    }
14880                    procsToKill.add(proc);
14881                }
14882            }
14883        }
14884
14885        synchronized(this) {
14886            if (procsToKill != null) {
14887                for (int i=procsToKill.size()-1; i>=0; i--) {
14888                    ProcessRecord proc = procsToKill.get(i);
14889                    Slog.i(TAG, "Removing system update proc: " + proc);
14890                    removeProcessLocked(proc, true, false, "system update done");
14891                }
14892            }
14893
14894            // Now that we have cleaned up any update processes, we
14895            // are ready to start launching real processes and know that
14896            // we won't trample on them any more.
14897            mProcessesReady = true;
14898        }
14899
14900        Slog.i(TAG, "System now ready");
14901        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14902            SystemClock.uptimeMillis());
14903
14904        synchronized(this) {
14905            // Make sure we have no pre-ready processes sitting around.
14906
14907            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14908                ResolveInfo ri = mContext.getPackageManager()
14909                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14910                                STOCK_PM_FLAGS);
14911                CharSequence errorMsg = null;
14912                if (ri != null) {
14913                    ActivityInfo ai = ri.activityInfo;
14914                    ApplicationInfo app = ai.applicationInfo;
14915                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14916                        mTopAction = Intent.ACTION_FACTORY_TEST;
14917                        mTopData = null;
14918                        mTopComponent = new ComponentName(app.packageName,
14919                                ai.name);
14920                    } else {
14921                        errorMsg = mContext.getResources().getText(
14922                                com.android.internal.R.string.factorytest_not_system);
14923                    }
14924                } else {
14925                    errorMsg = mContext.getResources().getText(
14926                            com.android.internal.R.string.factorytest_no_action);
14927                }
14928                if (errorMsg != null) {
14929                    mTopAction = null;
14930                    mTopData = null;
14931                    mTopComponent = null;
14932                    Message msg = Message.obtain();
14933                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14934                    msg.getData().putCharSequence("msg", errorMsg);
14935                    mUiHandler.sendMessage(msg);
14936                }
14937            }
14938        }
14939
14940        retrieveSettings();
14941        final int currentUserId = mUserController.getCurrentUserId();
14942        synchronized (this) {
14943            readGrantedUriPermissionsLocked();
14944        }
14945
14946        final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
14947        if (pmi != null) {
14948            pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
14949                    state -> updateForceBackgroundCheck(state.batterySaverEnabled));
14950            updateForceBackgroundCheck(
14951                    pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
14952        } else {
14953            Slog.wtf(TAG, "PowerManagerInternal not found.");
14954        }
14955
14956        if (goingCallback != null) goingCallback.run();
14957        traceLog.traceBegin("ActivityManagerStartApps");
14958        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14959                Integer.toString(currentUserId), currentUserId);
14960        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14961                Integer.toString(currentUserId), currentUserId);
14962        mSystemServiceManager.startUser(currentUserId);
14963
14964        synchronized (this) {
14965            // Only start up encryption-aware persistent apps; once user is
14966            // unlocked we'll come back around and start unaware apps
14967            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14968
14969            // Start up initial activity.
14970            mBooting = true;
14971            // Enable home activity for system user, so that the system can always boot. We don't
14972            // do this when the system user is not setup since the setup wizard should be the one
14973            // to handle home activity in this case.
14974            if (UserManager.isSplitSystemUser() &&
14975                    Settings.Secure.getInt(mContext.getContentResolver(),
14976                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14977                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14978                try {
14979                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14980                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14981                            UserHandle.USER_SYSTEM);
14982                } catch (RemoteException e) {
14983                    throw e.rethrowAsRuntimeException();
14984                }
14985            }
14986            startHomeActivityLocked(currentUserId, "systemReady");
14987
14988            try {
14989                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14990                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14991                            + " data partition or your device will be unstable.");
14992                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14993                }
14994            } catch (RemoteException e) {
14995            }
14996
14997            if (!Build.isBuildConsistent()) {
14998                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14999                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
15000            }
15001
15002            long ident = Binder.clearCallingIdentity();
15003            try {
15004                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
15005                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15006                        | Intent.FLAG_RECEIVER_FOREGROUND);
15007                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
15008                broadcastIntentLocked(null, null, intent,
15009                        null, null, 0, null, null, null, OP_NONE,
15010                        null, false, false, MY_PID, SYSTEM_UID,
15011                        currentUserId);
15012                intent = new Intent(Intent.ACTION_USER_STARTING);
15013                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15014                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
15015                broadcastIntentLocked(null, null, intent,
15016                        null, new IIntentReceiver.Stub() {
15017                            @Override
15018                            public void performReceive(Intent intent, int resultCode, String data,
15019                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
15020                                    throws RemoteException {
15021                            }
15022                        }, 0, null, null,
15023                        new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
15024                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
15025            } catch (Throwable t) {
15026                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
15027            } finally {
15028                Binder.restoreCallingIdentity(ident);
15029            }
15030            mStackSupervisor.resumeFocusedStackTopActivityLocked();
15031            mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
15032
15033            BinderInternal.nSetBinderProxyCountEnabled(true);
15034            BinderInternal.setBinderProxyCountCallback(
15035                    new BinderInternal.BinderProxyLimitListener() {
15036                        @Override
15037                        public void onLimitReached(int uid) {
15038                            Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
15039                                    + Process.myUid());
15040                            if (uid == Process.SYSTEM_UID) {
15041                                Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
15042                            } else {
15043                                killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
15044                                        "Too many Binders sent to SYSTEM");
15045                            }
15046                        }
15047                    }, mHandler);
15048
15049            traceLog.traceEnd(); // ActivityManagerStartApps
15050            traceLog.traceEnd(); // PhaseActivityManagerReady
15051        }
15052    }
15053
15054    private void updateForceBackgroundCheck(boolean enabled) {
15055        synchronized (this) {
15056            if (mForceBackgroundCheck != enabled) {
15057                mForceBackgroundCheck = enabled;
15058
15059                if (DEBUG_BACKGROUND_CHECK) {
15060                    Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
15061                }
15062
15063                if (mForceBackgroundCheck) {
15064                    // Stop background services for idle UIDs.
15065                    doStopUidForIdleUidsLocked();
15066                }
15067            }
15068        }
15069    }
15070
15071    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
15072        synchronized (this) {
15073            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
15074        }
15075    }
15076
15077    void skipCurrentReceiverLocked(ProcessRecord app) {
15078        for (BroadcastQueue queue : mBroadcastQueues) {
15079            queue.skipCurrentReceiverLocked(app);
15080        }
15081    }
15082
15083    /**
15084     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
15085     * The application process will exit immediately after this call returns.
15086     * @param app object of the crashing app, null for the system server
15087     * @param crashInfo describing the exception
15088     */
15089    public void handleApplicationCrash(IBinder app,
15090            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15091        ProcessRecord r = findAppProcess(app, "Crash");
15092        final String processName = app == null ? "system_server"
15093                : (r == null ? "unknown" : r.processName);
15094
15095        handleApplicationCrashInner("crash", r, processName, crashInfo);
15096    }
15097
15098    /* Native crash reporting uses this inner version because it needs to be somewhat
15099     * decoupled from the AM-managed cleanup lifecycle
15100     */
15101    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
15102            ApplicationErrorReport.CrashInfo crashInfo) {
15103        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
15104                UserHandle.getUserId(Binder.getCallingUid()), processName,
15105                r == null ? -1 : r.info.flags,
15106                crashInfo.exceptionClassName,
15107                crashInfo.exceptionMessage,
15108                crashInfo.throwFileName,
15109                crashInfo.throwLineNumber);
15110
15111        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
15112
15113        mAppErrors.crashApplication(r, crashInfo);
15114    }
15115
15116    public void handleApplicationStrictModeViolation(
15117            IBinder app,
15118            int violationMask,
15119            StrictMode.ViolationInfo info) {
15120        // We're okay if the ProcessRecord is missing; it probably means that
15121        // we're reporting a violation from the system process itself.
15122        final ProcessRecord r = findAppProcess(app, "StrictMode");
15123
15124        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
15125            Integer stackFingerprint = info.hashCode();
15126            boolean logIt = true;
15127            synchronized (mAlreadyLoggedViolatedStacks) {
15128                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
15129                    logIt = false;
15130                    // TODO: sub-sample into EventLog for these, with
15131                    // the info.durationMillis?  Then we'd get
15132                    // the relative pain numbers, without logging all
15133                    // the stack traces repeatedly.  We'd want to do
15134                    // likewise in the client code, which also does
15135                    // dup suppression, before the Binder call.
15136                } else {
15137                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
15138                        mAlreadyLoggedViolatedStacks.clear();
15139                    }
15140                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
15141                }
15142            }
15143            if (logIt) {
15144                logStrictModeViolationToDropBox(r, info);
15145            }
15146        }
15147
15148        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
15149            AppErrorResult result = new AppErrorResult();
15150            synchronized (this) {
15151                final long origId = Binder.clearCallingIdentity();
15152
15153                Message msg = Message.obtain();
15154                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
15155                HashMap<String, Object> data = new HashMap<String, Object>();
15156                data.put("result", result);
15157                data.put("app", r);
15158                data.put("violationMask", violationMask);
15159                data.put("info", info);
15160                msg.obj = data;
15161                mUiHandler.sendMessage(msg);
15162
15163                Binder.restoreCallingIdentity(origId);
15164            }
15165            int res = result.get();
15166            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
15167        }
15168    }
15169
15170    // Depending on the policy in effect, there could be a bunch of
15171    // these in quick succession so we try to batch these together to
15172    // minimize disk writes, number of dropbox entries, and maximize
15173    // compression, by having more fewer, larger records.
15174    private void logStrictModeViolationToDropBox(
15175            ProcessRecord process,
15176            StrictMode.ViolationInfo info) {
15177        if (info == null) {
15178            return;
15179        }
15180        final boolean isSystemApp = process == null ||
15181                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
15182                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
15183        final String processName = process == null ? "unknown" : process.processName;
15184        final DropBoxManager dbox = (DropBoxManager)
15185                mContext.getSystemService(Context.DROPBOX_SERVICE);
15186
15187        // Exit early if the dropbox isn't configured to accept this report type.
15188        final String dropboxTag = processClass(process) + "_strictmode";
15189        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15190
15191        final StringBuilder sb = new StringBuilder(1024);
15192        synchronized (sb) {
15193            appendDropBoxProcessHeaders(process, processName, sb);
15194            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15195            sb.append("System-App: ").append(isSystemApp).append("\n");
15196            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
15197            if (info.violationNumThisLoop != 0) {
15198                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
15199            }
15200            if (info.numAnimationsRunning != 0) {
15201                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
15202            }
15203            if (info.broadcastIntentAction != null) {
15204                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
15205            }
15206            if (info.durationMillis != -1) {
15207                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
15208            }
15209            if (info.numInstances != -1) {
15210                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
15211            }
15212            if (info.tags != null) {
15213                for (String tag : info.tags) {
15214                    sb.append("Span-Tag: ").append(tag).append("\n");
15215                }
15216            }
15217            sb.append("\n");
15218            sb.append(info.getStackTrace());
15219            sb.append("\n");
15220            if (info.getViolationDetails() != null) {
15221                sb.append(info.getViolationDetails());
15222                sb.append("\n");
15223            }
15224        }
15225
15226        final String res = sb.toString();
15227        IoThread.getHandler().post(() -> {
15228            dbox.addText(dropboxTag, res);
15229        });
15230    }
15231
15232    /**
15233     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
15234     * @param app object of the crashing app, null for the system server
15235     * @param tag reported by the caller
15236     * @param system whether this wtf is coming from the system
15237     * @param crashInfo describing the context of the error
15238     * @return true if the process should exit immediately (WTF is fatal)
15239     */
15240    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
15241            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15242        final int callingUid = Binder.getCallingUid();
15243        final int callingPid = Binder.getCallingPid();
15244
15245        if (system) {
15246            // If this is coming from the system, we could very well have low-level
15247            // system locks held, so we want to do this all asynchronously.  And we
15248            // never want this to become fatal, so there is that too.
15249            mHandler.post(new Runnable() {
15250                @Override public void run() {
15251                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
15252                }
15253            });
15254            return false;
15255        }
15256
15257        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
15258                crashInfo);
15259
15260        final boolean isFatal = Build.IS_ENG || Settings.Global
15261                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
15262        final boolean isSystem = (r == null) || r.persistent;
15263
15264        if (isFatal && !isSystem) {
15265            mAppErrors.crashApplication(r, crashInfo);
15266            return true;
15267        } else {
15268            return false;
15269        }
15270    }
15271
15272    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
15273            final ApplicationErrorReport.CrashInfo crashInfo) {
15274        final ProcessRecord r = findAppProcess(app, "WTF");
15275        final String processName = app == null ? "system_server"
15276                : (r == null ? "unknown" : r.processName);
15277
15278        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
15279                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
15280
15281        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
15282
15283        return r;
15284    }
15285
15286    /**
15287     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
15288     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
15289     */
15290    private ProcessRecord findAppProcess(IBinder app, String reason) {
15291        if (app == null) {
15292            return null;
15293        }
15294
15295        synchronized (this) {
15296            final int NP = mProcessNames.getMap().size();
15297            for (int ip=0; ip<NP; ip++) {
15298                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
15299                final int NA = apps.size();
15300                for (int ia=0; ia<NA; ia++) {
15301                    ProcessRecord p = apps.valueAt(ia);
15302                    if (p.thread != null && p.thread.asBinder() == app) {
15303                        return p;
15304                    }
15305                }
15306            }
15307
15308            Slog.w(TAG, "Can't find mystery application for " + reason
15309                    + " from pid=" + Binder.getCallingPid()
15310                    + " uid=" + Binder.getCallingUid() + ": " + app);
15311            return null;
15312        }
15313    }
15314
15315    /**
15316     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
15317     * to append various headers to the dropbox log text.
15318     */
15319    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
15320            StringBuilder sb) {
15321        // Watchdog thread ends up invoking this function (with
15322        // a null ProcessRecord) to add the stack file to dropbox.
15323        // Do not acquire a lock on this (am) in such cases, as it
15324        // could cause a potential deadlock, if and when watchdog
15325        // is invoked due to unavailability of lock on am and it
15326        // would prevent watchdog from killing system_server.
15327        if (process == null) {
15328            sb.append("Process: ").append(processName).append("\n");
15329            return;
15330        }
15331        // Note: ProcessRecord 'process' is guarded by the service
15332        // instance.  (notably process.pkgList, which could otherwise change
15333        // concurrently during execution of this method)
15334        synchronized (this) {
15335            sb.append("Process: ").append(processName).append("\n");
15336            sb.append("PID: ").append(process.pid).append("\n");
15337            int flags = process.info.flags;
15338            IPackageManager pm = AppGlobals.getPackageManager();
15339            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
15340            for (int ip=0; ip<process.pkgList.size(); ip++) {
15341                String pkg = process.pkgList.keyAt(ip);
15342                sb.append("Package: ").append(pkg);
15343                try {
15344                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
15345                    if (pi != null) {
15346                        sb.append(" v").append(pi.getLongVersionCode());
15347                        if (pi.versionName != null) {
15348                            sb.append(" (").append(pi.versionName).append(")");
15349                        }
15350                    }
15351                } catch (RemoteException e) {
15352                    Slog.e(TAG, "Error getting package info: " + pkg, e);
15353                }
15354                sb.append("\n");
15355            }
15356            if (process.info.isInstantApp()) {
15357                sb.append("Instant-App: true\n");
15358            }
15359        }
15360    }
15361
15362    private static String processClass(ProcessRecord process) {
15363        if (process == null || process.pid == MY_PID) {
15364            return "system_server";
15365        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15366            return "system_app";
15367        } else {
15368            return "data_app";
15369        }
15370    }
15371
15372    private volatile long mWtfClusterStart;
15373    private volatile int mWtfClusterCount;
15374
15375    /**
15376     * Write a description of an error (crash, WTF, ANR) to the drop box.
15377     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
15378     * @param process which caused the error, null means the system server
15379     * @param activity which triggered the error, null if unknown
15380     * @param parent activity related to the error, null if unknown
15381     * @param subject line related to the error, null if absent
15382     * @param report in long form describing the error, null if absent
15383     * @param dataFile text file to include in the report, null if none
15384     * @param crashInfo giving an application stack trace, null if absent
15385     */
15386    public void addErrorToDropBox(String eventType,
15387            ProcessRecord process, String processName, ActivityRecord activity,
15388            ActivityRecord parent, String subject,
15389            final String report, final File dataFile,
15390            final ApplicationErrorReport.CrashInfo crashInfo) {
15391        // NOTE -- this must never acquire the ActivityManagerService lock,
15392        // otherwise the watchdog may be prevented from resetting the system.
15393
15394        // Bail early if not published yet
15395        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
15396        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
15397
15398        // Exit early if the dropbox isn't configured to accept this report type.
15399        final String dropboxTag = processClass(process) + "_" + eventType;
15400        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15401
15402        // Log to StatsLog before the rate-limiting.
15403        // The logging below is adapated from appendDropboxProcessHeaders.
15404        StatsLog.write(StatsLog.DROPBOX_ERROR_CHANGED,
15405                process != null ? process.uid : -1,
15406                dropboxTag,
15407                processName,
15408                process != null ? process.pid : -1,
15409                (process != null && process.info != null) ?
15410                        (process.info.isInstantApp() ? 1 : 0) : -1,
15411                activity != null ? activity.shortComponentName : null,
15412                activity != null ? activity.packageName : null,
15413                process != null ? (process.isInterestingToUserLocked() ? 1 : 0) : -1);
15414
15415        // Rate-limit how often we're willing to do the heavy lifting below to
15416        // collect and record logs; currently 5 logs per 10 second period.
15417        final long now = SystemClock.elapsedRealtime();
15418        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
15419            mWtfClusterStart = now;
15420            mWtfClusterCount = 1;
15421        } else {
15422            if (mWtfClusterCount++ >= 5) return;
15423        }
15424
15425        final StringBuilder sb = new StringBuilder(1024);
15426        appendDropBoxProcessHeaders(process, processName, sb);
15427        if (process != null) {
15428            sb.append("Foreground: ")
15429                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
15430                    .append("\n");
15431        }
15432        if (activity != null) {
15433            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
15434        }
15435        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
15436            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
15437        }
15438        if (parent != null && parent != activity) {
15439            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
15440        }
15441        if (subject != null) {
15442            sb.append("Subject: ").append(subject).append("\n");
15443        }
15444        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15445        if (Debug.isDebuggerConnected()) {
15446            sb.append("Debugger: Connected\n");
15447        }
15448        sb.append("\n");
15449
15450        // Do the rest in a worker thread to avoid blocking the caller on I/O
15451        // (After this point, we shouldn't access AMS internal data structures.)
15452        Thread worker = new Thread("Error dump: " + dropboxTag) {
15453            @Override
15454            public void run() {
15455                if (report != null) {
15456                    sb.append(report);
15457                }
15458
15459                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
15460                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
15461                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
15462                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
15463
15464                if (dataFile != null && maxDataFileSize > 0) {
15465                    try {
15466                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
15467                                    "\n\n[[TRUNCATED]]"));
15468                    } catch (IOException e) {
15469                        Slog.e(TAG, "Error reading " + dataFile, e);
15470                    }
15471                }
15472                if (crashInfo != null && crashInfo.stackTrace != null) {
15473                    sb.append(crashInfo.stackTrace);
15474                }
15475
15476                if (lines > 0) {
15477                    sb.append("\n");
15478
15479                    // Merge several logcat streams, and take the last N lines
15480                    InputStreamReader input = null;
15481                    try {
15482                        java.lang.Process logcat = new ProcessBuilder(
15483                                "/system/bin/timeout", "-k", "15s", "10s",
15484                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
15485                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
15486                                        .redirectErrorStream(true).start();
15487
15488                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
15489                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
15490                        input = new InputStreamReader(logcat.getInputStream());
15491
15492                        int num;
15493                        char[] buf = new char[8192];
15494                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
15495                    } catch (IOException e) {
15496                        Slog.e(TAG, "Error running logcat", e);
15497                    } finally {
15498                        if (input != null) try { input.close(); } catch (IOException e) {}
15499                    }
15500                }
15501
15502                dbox.addText(dropboxTag, sb.toString());
15503            }
15504        };
15505
15506        if (process == null) {
15507            // If process is null, we are being called from some internal code
15508            // and may be about to die -- run this synchronously.
15509            final int oldMask = StrictMode.allowThreadDiskWritesMask();
15510            try {
15511                worker.run();
15512            } finally {
15513                StrictMode.setThreadPolicyMask(oldMask);
15514            }
15515        } else {
15516            worker.start();
15517        }
15518    }
15519
15520    @Override
15521    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
15522        enforceNotIsolatedCaller("getProcessesInErrorState");
15523        // assume our apps are happy - lazy create the list
15524        List<ActivityManager.ProcessErrorStateInfo> errList = null;
15525
15526        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15527                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
15528        int userId = UserHandle.getUserId(Binder.getCallingUid());
15529
15530        synchronized (this) {
15531
15532            // iterate across all processes
15533            for (int i=mLruProcesses.size()-1; i>=0; i--) {
15534                ProcessRecord app = mLruProcesses.get(i);
15535                if (!allUsers && app.userId != userId) {
15536                    continue;
15537                }
15538                if ((app.thread != null) && (app.crashing || app.notResponding)) {
15539                    // This one's in trouble, so we'll generate a report for it
15540                    // crashes are higher priority (in case there's a crash *and* an anr)
15541                    ActivityManager.ProcessErrorStateInfo report = null;
15542                    if (app.crashing) {
15543                        report = app.crashingReport;
15544                    } else if (app.notResponding) {
15545                        report = app.notRespondingReport;
15546                    }
15547
15548                    if (report != null) {
15549                        if (errList == null) {
15550                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
15551                        }
15552                        errList.add(report);
15553                    } else {
15554                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
15555                                " crashing = " + app.crashing +
15556                                " notResponding = " + app.notResponding);
15557                    }
15558                }
15559            }
15560        }
15561
15562        return errList;
15563    }
15564
15565    static int procStateToImportance(int procState, int memAdj,
15566            ActivityManager.RunningAppProcessInfo currApp,
15567            int clientTargetSdk) {
15568        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
15569                procState, clientTargetSdk);
15570        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
15571            currApp.lru = memAdj;
15572        } else {
15573            currApp.lru = 0;
15574        }
15575        return imp;
15576    }
15577
15578    private void fillInProcMemInfo(ProcessRecord app,
15579            ActivityManager.RunningAppProcessInfo outInfo,
15580            int clientTargetSdk) {
15581        outInfo.pid = app.pid;
15582        outInfo.uid = app.info.uid;
15583        if (mHeavyWeightProcess == app) {
15584            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
15585        }
15586        if (app.persistent) {
15587            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
15588        }
15589        if (app.activities.size() > 0) {
15590            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
15591        }
15592        outInfo.lastTrimLevel = app.trimMemoryLevel;
15593        int adj = app.curAdj;
15594        int procState = app.curProcState;
15595        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
15596        outInfo.importanceReasonCode = app.adjTypeCode;
15597        outInfo.processState = app.curProcState;
15598    }
15599
15600    @Override
15601    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
15602        enforceNotIsolatedCaller("getRunningAppProcesses");
15603
15604        final int callingUid = Binder.getCallingUid();
15605        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15606
15607        // Lazy instantiation of list
15608        List<ActivityManager.RunningAppProcessInfo> runList = null;
15609        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15610                callingUid) == PackageManager.PERMISSION_GRANTED;
15611        final int userId = UserHandle.getUserId(callingUid);
15612        final boolean allUids = isGetTasksAllowed(
15613                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
15614
15615        synchronized (this) {
15616            // Iterate across all processes
15617            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15618                ProcessRecord app = mLruProcesses.get(i);
15619                if ((!allUsers && app.userId != userId)
15620                        || (!allUids && app.uid != callingUid)) {
15621                    continue;
15622                }
15623                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
15624                    // Generate process state info for running application
15625                    ActivityManager.RunningAppProcessInfo currApp =
15626                        new ActivityManager.RunningAppProcessInfo(app.processName,
15627                                app.pid, app.getPackageList());
15628                    fillInProcMemInfo(app, currApp, clientTargetSdk);
15629                    if (app.adjSource instanceof ProcessRecord) {
15630                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
15631                        currApp.importanceReasonImportance =
15632                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
15633                                        app.adjSourceProcState);
15634                    } else if (app.adjSource instanceof ActivityRecord) {
15635                        ActivityRecord r = (ActivityRecord)app.adjSource;
15636                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
15637                    }
15638                    if (app.adjTarget instanceof ComponentName) {
15639                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
15640                    }
15641                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
15642                    //        + " lru=" + currApp.lru);
15643                    if (runList == null) {
15644                        runList = new ArrayList<>();
15645                    }
15646                    runList.add(currApp);
15647                }
15648            }
15649        }
15650        return runList;
15651    }
15652
15653    @Override
15654    public List<ApplicationInfo> getRunningExternalApplications() {
15655        enforceNotIsolatedCaller("getRunningExternalApplications");
15656        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
15657        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
15658        if (runningApps != null && runningApps.size() > 0) {
15659            Set<String> extList = new HashSet<String>();
15660            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
15661                if (app.pkgList != null) {
15662                    for (String pkg : app.pkgList) {
15663                        extList.add(pkg);
15664                    }
15665                }
15666            }
15667            IPackageManager pm = AppGlobals.getPackageManager();
15668            for (String pkg : extList) {
15669                try {
15670                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
15671                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
15672                        retList.add(info);
15673                    }
15674                } catch (RemoteException e) {
15675                }
15676            }
15677        }
15678        return retList;
15679    }
15680
15681    @Override
15682    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15683        enforceNotIsolatedCaller("getMyMemoryState");
15684
15685        final int callingUid = Binder.getCallingUid();
15686        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15687
15688        synchronized (this) {
15689            ProcessRecord proc;
15690            synchronized (mPidsSelfLocked) {
15691                proc = mPidsSelfLocked.get(Binder.getCallingPid());
15692            }
15693            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15694        }
15695    }
15696
15697    @Override
15698    public int getMemoryTrimLevel() {
15699        enforceNotIsolatedCaller("getMyMemoryState");
15700        synchronized (this) {
15701            return mLastMemoryLevel;
15702        }
15703    }
15704
15705    @Override
15706    public void onShellCommand(FileDescriptor in, FileDescriptor out,
15707            FileDescriptor err, String[] args, ShellCallback callback,
15708            ResultReceiver resultReceiver) {
15709        (new ActivityManagerShellCommand(this, false)).exec(
15710                this, in, out, err, args, callback, resultReceiver);
15711    }
15712
15713    SleepToken acquireSleepToken(String tag, int displayId) {
15714        synchronized (this) {
15715            final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15716            updateSleepIfNeededLocked();
15717            return token;
15718        }
15719    }
15720
15721    @Override
15722    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15723        PriorityDump.dump(mPriorityDumper, fd, pw, args);
15724    }
15725
15726    /**
15727     * Wrapper function to print out debug data filtered by specified arguments.
15728    */
15729    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
15730        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15731
15732        boolean dumpAll = false;
15733        boolean dumpClient = false;
15734        boolean dumpCheckin = false;
15735        boolean dumpCheckinFormat = false;
15736        boolean dumpNormalPriority = false;
15737        boolean dumpVisibleStacksOnly = false;
15738        boolean dumpFocusedStackOnly = false;
15739        String dumpPackage = null;
15740
15741        int opti = 0;
15742        while (opti < args.length) {
15743            String opt = args[opti];
15744            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15745                break;
15746            }
15747            opti++;
15748            if ("-a".equals(opt)) {
15749                dumpAll = true;
15750            } else if ("-c".equals(opt)) {
15751                dumpClient = true;
15752            } else if ("-v".equals(opt)) {
15753                dumpVisibleStacksOnly = true;
15754            } else if ("-f".equals(opt)) {
15755                dumpFocusedStackOnly = true;
15756            } else if ("-p".equals(opt)) {
15757                if (opti < args.length) {
15758                    dumpPackage = args[opti];
15759                    opti++;
15760                } else {
15761                    pw.println("Error: -p option requires package argument");
15762                    return;
15763                }
15764                dumpClient = true;
15765            } else if ("--checkin".equals(opt)) {
15766                dumpCheckin = dumpCheckinFormat = true;
15767            } else if ("-C".equals(opt)) {
15768                dumpCheckinFormat = true;
15769            } else if ("--normal-priority".equals(opt)) {
15770                dumpNormalPriority = true;
15771            } else if ("-h".equals(opt)) {
15772                ActivityManagerShellCommand.dumpHelp(pw, true);
15773                return;
15774            } else {
15775                pw.println("Unknown argument: " + opt + "; use -h for help");
15776            }
15777        }
15778
15779        long origId = Binder.clearCallingIdentity();
15780
15781        if (useProto) {
15782            final ProtoOutputStream proto = new ProtoOutputStream(fd);
15783            String cmd = opti < args.length ? args[opti] : "";
15784            opti++;
15785
15786            if ("activities".equals(cmd) || "a".equals(cmd)) {
15787                // output proto is ActivityManagerServiceDumpActivitiesProto
15788                synchronized (this) {
15789                    writeActivitiesToProtoLocked(proto);
15790                }
15791            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15792                // output proto is ActivityManagerServiceDumpBroadcastsProto
15793                synchronized (this) {
15794                    writeBroadcastsToProtoLocked(proto);
15795                }
15796            } else if ("provider".equals(cmd)) {
15797                String[] newArgs;
15798                String name;
15799                if (opti >= args.length) {
15800                    name = null;
15801                    newArgs = EMPTY_STRING_ARRAY;
15802                } else {
15803                    name = args[opti];
15804                    opti++;
15805                    newArgs = new String[args.length - opti];
15806                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15807                            args.length - opti);
15808                }
15809                if (!dumpProviderProto(fd, pw, name, newArgs)) {
15810                    pw.println("No providers match: " + name);
15811                    pw.println("Use -h for help.");
15812                }
15813            } else if ("service".equals(cmd)) {
15814                // output proto is ActivityManagerServiceDumpServicesProto
15815                mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
15816            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15817                if (opti < args.length) {
15818                    dumpPackage = args[opti];
15819                    opti++;
15820                }
15821                // output proto is ProcessProto
15822                synchronized (this) {
15823                    writeProcessesToProtoLocked(proto, dumpPackage);
15824                }
15825            } else {
15826                // default option, dump everything, output is ActivityManagerServiceProto
15827                synchronized (this) {
15828                    long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
15829                    writeActivitiesToProtoLocked(proto);
15830                    proto.end(activityToken);
15831
15832                    long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
15833                    writeBroadcastsToProtoLocked(proto);
15834                    proto.end(broadcastToken);
15835
15836                    long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
15837                    mServices.writeToProto(proto, ActivityManagerServiceDumpServicesProto.ACTIVE_SERVICES);
15838                    proto.end(serviceToken);
15839
15840                    long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
15841                    writeProcessesToProtoLocked(proto, dumpPackage);
15842                    proto.end(processToken);
15843                }
15844            }
15845            proto.flush();
15846            Binder.restoreCallingIdentity(origId);
15847            return;
15848        }
15849
15850        int dumpAppId = getAppId(dumpPackage);
15851        boolean more = false;
15852        // Is the caller requesting to dump a particular piece of data?
15853        if (opti < args.length) {
15854            String cmd = args[opti];
15855            opti++;
15856            if ("activities".equals(cmd) || "a".equals(cmd)) {
15857                synchronized (this) {
15858                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15859                }
15860            } else if ("lastanr".equals(cmd)) {
15861                synchronized (this) {
15862                    dumpLastANRLocked(pw);
15863                }
15864            } else if ("starter".equals(cmd)) {
15865                synchronized (this) {
15866                    dumpActivityStarterLocked(pw, dumpPackage);
15867                }
15868            } else if ("containers".equals(cmd)) {
15869                synchronized (this) {
15870                    dumpActivityContainersLocked(pw);
15871                }
15872            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15873                synchronized (this) {
15874                    if (mRecentTasks != null) {
15875                        mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
15876                    }
15877                }
15878            } else if ("binder-proxies".equals(cmd)) {
15879                if (opti >= args.length) {
15880                    dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
15881                            "Counts of Binder Proxies held by SYSTEM");
15882                } else {
15883                    String uid = args[opti];
15884                    opti++;
15885                    // Ensure Binder Proxy Count is as up to date as possible
15886                    System.gc();
15887                    System.runFinalization();
15888                    System.gc();
15889                    pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
15890                }
15891            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15892                if (opti < args.length) {
15893                    dumpPackage = args[opti];
15894                    opti++;
15895                }
15896                synchronized (this) {
15897                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15898                }
15899            } else if ("broadcast-stats".equals(cmd)) {
15900                if (opti < args.length) {
15901                    dumpPackage = args[opti];
15902                    opti++;
15903                }
15904                synchronized (this) {
15905                    if (dumpCheckinFormat) {
15906                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15907                                dumpPackage);
15908                    } else {
15909                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15910                    }
15911                }
15912            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15913                if (opti < args.length) {
15914                    dumpPackage = args[opti];
15915                    opti++;
15916                }
15917                synchronized (this) {
15918                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15919                }
15920            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15921                if (opti < args.length) {
15922                    dumpPackage = args[opti];
15923                    opti++;
15924                }
15925                synchronized (this) {
15926                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
15927                }
15928            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15929                synchronized (this) {
15930                    dumpOomLocked(fd, pw, args, opti, true);
15931                }
15932            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15933                synchronized (this) {
15934                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
15935                }
15936            } else if ("provider".equals(cmd)) {
15937                String[] newArgs;
15938                String name;
15939                if (opti >= args.length) {
15940                    name = null;
15941                    newArgs = EMPTY_STRING_ARRAY;
15942                } else {
15943                    name = args[opti];
15944                    opti++;
15945                    newArgs = new String[args.length - opti];
15946                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15947                }
15948                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15949                    pw.println("No providers match: " + name);
15950                    pw.println("Use -h for help.");
15951                }
15952            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15953                synchronized (this) {
15954                    dumpProvidersLocked(fd, pw, args, opti, true, null);
15955                }
15956            } else if ("service".equals(cmd)) {
15957                String[] newArgs;
15958                String name;
15959                if (opti >= args.length) {
15960                    name = null;
15961                    newArgs = EMPTY_STRING_ARRAY;
15962                } else {
15963                    name = args[opti];
15964                    opti++;
15965                    newArgs = new String[args.length - opti];
15966                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15967                            args.length - opti);
15968                }
15969                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15970                    pw.println("No services match: " + name);
15971                    pw.println("Use -h for help.");
15972                }
15973            } else if ("package".equals(cmd)) {
15974                String[] newArgs;
15975                if (opti >= args.length) {
15976                    pw.println("package: no package name specified");
15977                    pw.println("Use -h for help.");
15978                } else {
15979                    dumpPackage = args[opti];
15980                    opti++;
15981                    newArgs = new String[args.length - opti];
15982                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15983                            args.length - opti);
15984                    args = newArgs;
15985                    opti = 0;
15986                    more = true;
15987                }
15988            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15989                synchronized (this) {
15990                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15991                }
15992            } else if ("settings".equals(cmd)) {
15993                synchronized (this) {
15994                    mConstants.dump(pw);
15995                }
15996            } else if ("services".equals(cmd) || "s".equals(cmd)) {
15997                if (dumpClient) {
15998                    ActiveServices.ServiceDumper dumper;
15999                    synchronized (this) {
16000                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16001                                dumpPackage);
16002                    }
16003                    dumper.dumpWithClient();
16004                } else {
16005                    synchronized (this) {
16006                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
16007                                dumpPackage).dumpLocked();
16008                    }
16009                }
16010            } else if ("locks".equals(cmd)) {
16011                LockGuard.dump(fd, pw, args);
16012            } else {
16013                // Dumping a single activity?
16014                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
16015                        dumpFocusedStackOnly)) {
16016                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
16017                    int res = shell.exec(this, null, fd, null, args, null,
16018                            new ResultReceiver(null));
16019                    if (res < 0) {
16020                        pw.println("Bad activity command, or no activities match: " + cmd);
16021                        pw.println("Use -h for help.");
16022                    }
16023                }
16024            }
16025            if (!more) {
16026                Binder.restoreCallingIdentity(origId);
16027                return;
16028            }
16029        }
16030
16031        // No piece of data specified, dump everything.
16032        if (dumpCheckinFormat) {
16033            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
16034        } else if (dumpClient) {
16035            ActiveServices.ServiceDumper sdumper;
16036            synchronized (this) {
16037                mConstants.dump(pw);
16038                pw.println();
16039                if (dumpAll) {
16040                    pw.println("-------------------------------------------------------------------------------");
16041                }
16042                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16043                pw.println();
16044                if (dumpAll) {
16045                    pw.println("-------------------------------------------------------------------------------");
16046                }
16047                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16048                pw.println();
16049                if (dumpAll) {
16050                    pw.println("-------------------------------------------------------------------------------");
16051                }
16052                if (dumpAll || dumpPackage != null) {
16053                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16054                    pw.println();
16055                    if (dumpAll) {
16056                        pw.println("-------------------------------------------------------------------------------");
16057                    }
16058                }
16059                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16060                pw.println();
16061                if (dumpAll) {
16062                    pw.println("-------------------------------------------------------------------------------");
16063                }
16064                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16065                pw.println();
16066                if (dumpAll) {
16067                    pw.println("-------------------------------------------------------------------------------");
16068                }
16069                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
16070                        dumpPackage);
16071            }
16072            sdumper.dumpWithClient();
16073            pw.println();
16074            synchronized (this) {
16075                if (dumpAll) {
16076                    pw.println("-------------------------------------------------------------------------------");
16077                }
16078                if (mRecentTasks != null) {
16079                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
16080                }
16081                pw.println();
16082                if (dumpAll) {
16083                    pw.println("-------------------------------------------------------------------------------");
16084                }
16085                dumpLastANRLocked(pw);
16086                pw.println();
16087                if (dumpAll) {
16088                    pw.println("-------------------------------------------------------------------------------");
16089                }
16090                dumpActivityStarterLocked(pw, dumpPackage);
16091                pw.println();
16092                if (dumpAll) {
16093                    pw.println("-------------------------------------------------------------------------------");
16094                }
16095                dumpActivityContainersLocked(pw);
16096                pw.println();
16097                if (dumpAll) {
16098                    pw.println("-------------------------------------------------------------------------------");
16099                }
16100                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16101                if (mAssociations.size() > 0) {
16102                    pw.println();
16103                    if (dumpAll) {
16104                        pw.println("-------------------------------------------------------------------------------");
16105                    }
16106                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16107                }
16108                pw.println();
16109                if (dumpAll) {
16110                    pw.println("-------------------------------------------------------------------------------");
16111                }
16112                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16113            }
16114
16115        } else {
16116            synchronized (this) {
16117                mConstants.dump(pw);
16118                pw.println();
16119                if (dumpAll) {
16120                    pw.println("-------------------------------------------------------------------------------");
16121                }
16122                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16123                pw.println();
16124                if (dumpAll) {
16125                    pw.println("-------------------------------------------------------------------------------");
16126                }
16127                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16128                pw.println();
16129                if (dumpAll) {
16130                    pw.println("-------------------------------------------------------------------------------");
16131                }
16132                if (dumpAll || dumpPackage != null) {
16133                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16134                    pw.println();
16135                    if (dumpAll) {
16136                        pw.println("-------------------------------------------------------------------------------");
16137                    }
16138                }
16139                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16140                pw.println();
16141                if (dumpAll) {
16142                    pw.println("-------------------------------------------------------------------------------");
16143                }
16144                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16145                pw.println();
16146                if (dumpAll) {
16147                    pw.println("-------------------------------------------------------------------------------");
16148                }
16149                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
16150                        .dumpLocked();
16151                pw.println();
16152                if (dumpAll) {
16153                    pw.println("-------------------------------------------------------------------------------");
16154                }
16155                if (mRecentTasks != null) {
16156                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
16157                }
16158                pw.println();
16159                if (dumpAll) {
16160                    pw.println("-------------------------------------------------------------------------------");
16161                }
16162                dumpLastANRLocked(pw);
16163                pw.println();
16164                if (dumpAll) {
16165                    pw.println("-------------------------------------------------------------------------------");
16166                }
16167                dumpActivityStarterLocked(pw, dumpPackage);
16168                pw.println();
16169                if (dumpAll) {
16170                    pw.println("-------------------------------------------------------------------------------");
16171                }
16172                dumpActivityContainersLocked(pw);
16173                // Activities section is dumped as part of the Critical priority dump. Exclude the
16174                // section if priority is Normal.
16175                if (!dumpNormalPriority){
16176                    pw.println();
16177                    if (dumpAll) {
16178                        pw.println("-------------------------------------------------------------------------------");
16179                    }
16180                    dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16181                }
16182                if (mAssociations.size() > 0) {
16183                    pw.println();
16184                    if (dumpAll) {
16185                        pw.println("-------------------------------------------------------------------------------");
16186                    }
16187                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16188                }
16189                pw.println();
16190                if (dumpAll) {
16191                    pw.println("-------------------------------------------------------------------------------");
16192                }
16193                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16194            }
16195        }
16196        Binder.restoreCallingIdentity(origId);
16197    }
16198
16199    private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
16200        // The output proto of "activity --proto activities" is ActivityManagerServiceDumpActivitiesProto
16201        mStackSupervisor.writeToProto(proto, ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
16202    }
16203
16204    private void dumpLastANRLocked(PrintWriter pw) {
16205        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
16206        if (mLastANRState == null) {
16207            pw.println("  <no ANR has occurred since boot>");
16208        } else {
16209            pw.println(mLastANRState);
16210        }
16211    }
16212
16213    private void dumpActivityContainersLocked(PrintWriter pw) {
16214        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
16215        mStackSupervisor.dumpChildrenNames(pw, " ");
16216        pw.println(" ");
16217    }
16218
16219    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
16220        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
16221        mActivityStartController.dump(pw, "", dumpPackage);
16222    }
16223
16224    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16225            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16226        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
16227                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
16228    }
16229
16230    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16231            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
16232        pw.println(header);
16233
16234        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
16235                dumpPackage);
16236        boolean needSep = printedAnything;
16237
16238        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
16239                mStackSupervisor.getResumedActivityLocked(),
16240                dumpPackage, needSep, "  ResumedActivity: ");
16241        if (printed) {
16242            printedAnything = true;
16243            needSep = false;
16244        }
16245
16246        if (dumpPackage == null) {
16247            if (needSep) {
16248                pw.println();
16249            }
16250            printedAnything = true;
16251            mStackSupervisor.dump(pw, "  ");
16252        }
16253
16254        if (!printedAnything) {
16255            pw.println("  (nothing)");
16256        }
16257    }
16258
16259    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16260            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16261        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
16262
16263        int dumpUid = 0;
16264        if (dumpPackage != null) {
16265            IPackageManager pm = AppGlobals.getPackageManager();
16266            try {
16267                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
16268            } catch (RemoteException e) {
16269            }
16270        }
16271
16272        boolean printedAnything = false;
16273
16274        final long now = SystemClock.uptimeMillis();
16275
16276        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
16277            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
16278                    = mAssociations.valueAt(i1);
16279            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
16280                SparseArray<ArrayMap<String, Association>> sourceUids
16281                        = targetComponents.valueAt(i2);
16282                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
16283                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
16284                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
16285                        Association ass = sourceProcesses.valueAt(i4);
16286                        if (dumpPackage != null) {
16287                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
16288                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
16289                                continue;
16290                            }
16291                        }
16292                        printedAnything = true;
16293                        pw.print("  ");
16294                        pw.print(ass.mTargetProcess);
16295                        pw.print("/");
16296                        UserHandle.formatUid(pw, ass.mTargetUid);
16297                        pw.print(" <- ");
16298                        pw.print(ass.mSourceProcess);
16299                        pw.print("/");
16300                        UserHandle.formatUid(pw, ass.mSourceUid);
16301                        pw.println();
16302                        pw.print("    via ");
16303                        pw.print(ass.mTargetComponent.flattenToShortString());
16304                        pw.println();
16305                        pw.print("    ");
16306                        long dur = ass.mTime;
16307                        if (ass.mNesting > 0) {
16308                            dur += now - ass.mStartTime;
16309                        }
16310                        TimeUtils.formatDuration(dur, pw);
16311                        pw.print(" (");
16312                        pw.print(ass.mCount);
16313                        pw.print(" times)");
16314                        pw.print("  ");
16315                        for (int i=0; i<ass.mStateTimes.length; i++) {
16316                            long amt = ass.mStateTimes[i];
16317                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16318                                amt += now - ass.mLastStateUptime;
16319                            }
16320                            if (amt != 0) {
16321                                pw.print(" ");
16322                                pw.print(ProcessList.makeProcStateString(
16323                                            i + ActivityManager.MIN_PROCESS_STATE));
16324                                pw.print("=");
16325                                TimeUtils.formatDuration(amt, pw);
16326                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16327                                    pw.print("*");
16328                                }
16329                            }
16330                        }
16331                        pw.println();
16332                        if (ass.mNesting > 0) {
16333                            pw.print("    Currently active: ");
16334                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
16335                            pw.println();
16336                        }
16337                    }
16338                }
16339            }
16340
16341        }
16342
16343        if (!printedAnything) {
16344            pw.println("  (nothing)");
16345        }
16346    }
16347
16348    private int getAppId(String dumpPackage) {
16349        if (dumpPackage != null) {
16350            try {
16351                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
16352                        dumpPackage, 0);
16353                return UserHandle.getAppId(info.uid);
16354            } catch (NameNotFoundException e) {
16355                e.printStackTrace();
16356            }
16357        }
16358        return -1;
16359    }
16360
16361    boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
16362                String header, boolean needSep) {
16363        boolean printed = false;
16364        for (int i=0; i<uids.size(); i++) {
16365            UidRecord uidRec = uids.valueAt(i);
16366            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
16367                continue;
16368            }
16369            if (!printed) {
16370                printed = true;
16371                if (needSep) {
16372                    pw.println();
16373                }
16374                pw.print("  ");
16375                pw.println(header);
16376                needSep = true;
16377            }
16378            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
16379            pw.print(": "); pw.println(uidRec);
16380        }
16381        return printed;
16382    }
16383
16384    boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
16385        if(counts != null) {
16386            pw.println(header);
16387            for (int i = 0; i < counts.size(); i++) {
16388                final int uid = counts.keyAt(i);
16389                final int binderCount = counts.valueAt(i);
16390                pw.print("    UID ");
16391                pw.print(uid);
16392                pw.print(", binder count = ");
16393                pw.print(binderCount);
16394                pw.print(", package(s)= ");
16395                final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
16396                if (pkgNames != null) {
16397                    for (int j = 0; j < pkgNames.length; j++) {
16398                        pw.print(pkgNames[j]);
16399                        pw.print("; ");
16400                    }
16401                } else {
16402                    pw.print("NO PACKAGE NAME FOUND");
16403                }
16404                pw.println();
16405            }
16406            pw.println();
16407            return true;
16408        }
16409        return false;
16410    }
16411
16412    @GuardedBy("this")
16413    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16414            int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
16415        boolean needSep = false;
16416        int numPers = 0;
16417
16418        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
16419
16420        if (dumpAll) {
16421            final int NP = mProcessNames.getMap().size();
16422            for (int ip=0; ip<NP; ip++) {
16423                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16424                final int NA = procs.size();
16425                for (int ia=0; ia<NA; ia++) {
16426                    ProcessRecord r = procs.valueAt(ia);
16427                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16428                        continue;
16429                    }
16430                    if (!needSep) {
16431                        pw.println("  All known processes:");
16432                        needSep = true;
16433                    }
16434                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
16435                        pw.print(" UID "); pw.print(procs.keyAt(ia));
16436                        pw.print(" "); pw.println(r);
16437                    r.dump(pw, "    ");
16438                    if (r.persistent) {
16439                        numPers++;
16440                    }
16441                }
16442            }
16443        }
16444
16445        if (mIsolatedProcesses.size() > 0) {
16446            boolean printed = false;
16447            for (int i=0; i<mIsolatedProcesses.size(); i++) {
16448                ProcessRecord r = mIsolatedProcesses.valueAt(i);
16449                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16450                    continue;
16451                }
16452                if (!printed) {
16453                    if (needSep) {
16454                        pw.println();
16455                    }
16456                    pw.println("  Isolated process list (sorted by uid):");
16457                    printed = true;
16458                    needSep = true;
16459                }
16460                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
16461                pw.println(r);
16462            }
16463        }
16464
16465        if (mActiveInstrumentation.size() > 0) {
16466            boolean printed = false;
16467            for (int i=0; i<mActiveInstrumentation.size(); i++) {
16468                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16469                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16470                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16471                    continue;
16472                }
16473                if (!printed) {
16474                    if (needSep) {
16475                        pw.println();
16476                    }
16477                    pw.println("  Active instrumentation:");
16478                    printed = true;
16479                    needSep = true;
16480                }
16481                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
16482                pw.println(ai);
16483                ai.dump(pw, "      ");
16484            }
16485        }
16486
16487        if (mActiveUids.size() > 0) {
16488            if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
16489                needSep = true;
16490            }
16491        }
16492        if (dumpAll) {
16493            if (mValidateUids.size() > 0) {
16494                if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
16495                        needSep)) {
16496                    needSep = true;
16497                }
16498            }
16499        }
16500
16501        if (mLruProcesses.size() > 0) {
16502            if (needSep) {
16503                pw.println();
16504            }
16505            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
16506                    pw.print(" total, non-act at ");
16507                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16508                    pw.print(", non-svc at ");
16509                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16510                    pw.println("):");
16511            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
16512            needSep = true;
16513        }
16514
16515        if (dumpAll || dumpPackage != null) {
16516            synchronized (mPidsSelfLocked) {
16517                boolean printed = false;
16518                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16519                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16520                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16521                        continue;
16522                    }
16523                    if (!printed) {
16524                        if (needSep) pw.println();
16525                        needSep = true;
16526                        pw.println("  PID mappings:");
16527                        printed = true;
16528                    }
16529                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
16530                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
16531                }
16532            }
16533        }
16534
16535        if (mImportantProcesses.size() > 0) {
16536            synchronized (mPidsSelfLocked) {
16537                boolean printed = false;
16538                for (int i = 0; i< mImportantProcesses.size(); i++) {
16539                    ProcessRecord r = mPidsSelfLocked.get(
16540                            mImportantProcesses.valueAt(i).pid);
16541                    if (dumpPackage != null && (r == null
16542                            || !r.pkgList.containsKey(dumpPackage))) {
16543                        continue;
16544                    }
16545                    if (!printed) {
16546                        if (needSep) pw.println();
16547                        needSep = true;
16548                        pw.println("  Foreground Processes:");
16549                        printed = true;
16550                    }
16551                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
16552                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
16553                }
16554            }
16555        }
16556
16557        if (mPersistentStartingProcesses.size() > 0) {
16558            if (needSep) pw.println();
16559            needSep = true;
16560            pw.println("  Persisent processes that are starting:");
16561            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
16562                    "Starting Norm", "Restarting PERS", dumpPackage);
16563        }
16564
16565        if (mRemovedProcesses.size() > 0) {
16566            if (needSep) pw.println();
16567            needSep = true;
16568            pw.println("  Processes that are being removed:");
16569            dumpProcessList(pw, this, mRemovedProcesses, "    ",
16570                    "Removed Norm", "Removed PERS", dumpPackage);
16571        }
16572
16573        if (mProcessesOnHold.size() > 0) {
16574            if (needSep) pw.println();
16575            needSep = true;
16576            pw.println("  Processes that are on old until the system is ready:");
16577            dumpProcessList(pw, this, mProcessesOnHold, "    ",
16578                    "OnHold Norm", "OnHold PERS", dumpPackage);
16579        }
16580
16581        needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
16582
16583        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
16584
16585        if (dumpPackage == null) {
16586            pw.println();
16587            needSep = false;
16588            mUserController.dump(pw, dumpAll);
16589        }
16590        if (mHomeProcess != null && (dumpPackage == null
16591                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16592            if (needSep) {
16593                pw.println();
16594                needSep = false;
16595            }
16596            pw.println("  mHomeProcess: " + mHomeProcess);
16597        }
16598        if (mPreviousProcess != null && (dumpPackage == null
16599                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16600            if (needSep) {
16601                pw.println();
16602                needSep = false;
16603            }
16604            pw.println("  mPreviousProcess: " + mPreviousProcess);
16605        }
16606        if (dumpAll && (mPreviousProcess == null || dumpPackage == null
16607                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16608            StringBuilder sb = new StringBuilder(128);
16609            sb.append("  mPreviousProcessVisibleTime: ");
16610            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
16611            pw.println(sb);
16612        }
16613        if (mHeavyWeightProcess != null && (dumpPackage == null
16614                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16615            if (needSep) {
16616                pw.println();
16617                needSep = false;
16618            }
16619            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16620        }
16621        if (dumpAll && mPendingStarts.size() > 0) {
16622            if (needSep) pw.println();
16623            needSep = true;
16624            pw.println("  mPendingStarts: ");
16625            for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
16626                pw.println("    " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
16627            }
16628        }
16629        if (dumpPackage == null) {
16630            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
16631            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
16632        }
16633        if (dumpAll) {
16634            if (dumpPackage == null) {
16635                pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
16636            }
16637            if (mCompatModePackages.getPackages().size() > 0) {
16638                boolean printed = false;
16639                for (Map.Entry<String, Integer> entry
16640                        : mCompatModePackages.getPackages().entrySet()) {
16641                    String pkg = entry.getKey();
16642                    int mode = entry.getValue();
16643                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
16644                        continue;
16645                    }
16646                    if (!printed) {
16647                        pw.println("  mScreenCompatPackages:");
16648                        printed = true;
16649                    }
16650                    pw.print("    "); pw.print(pkg); pw.print(": ");
16651                            pw.print(mode); pw.println();
16652                }
16653            }
16654            final int NI = mUidObservers.getRegisteredCallbackCount();
16655            boolean printed = false;
16656            for (int i=0; i<NI; i++) {
16657                final UidObserverRegistration reg = (UidObserverRegistration)
16658                        mUidObservers.getRegisteredCallbackCookie(i);
16659                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
16660                    if (!printed) {
16661                        pw.println("  mUidObservers:");
16662                        printed = true;
16663                    }
16664                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
16665                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
16666                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
16667                        pw.print(" IDLE");
16668                    }
16669                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
16670                        pw.print(" ACT" );
16671                    }
16672                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
16673                        pw.print(" GONE");
16674                    }
16675                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
16676                        pw.print(" STATE");
16677                        pw.print(" (cut="); pw.print(reg.cutpoint);
16678                        pw.print(")");
16679                    }
16680                    pw.println();
16681                    if (reg.lastProcStates != null) {
16682                        final int NJ = reg.lastProcStates.size();
16683                        for (int j=0; j<NJ; j++) {
16684                            pw.print("      Last ");
16685                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
16686                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
16687                        }
16688                    }
16689                }
16690            }
16691            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
16692            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
16693            if (mPendingTempWhitelist.size() > 0) {
16694                pw.println("  mPendingTempWhitelist:");
16695                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
16696                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
16697                    pw.print("    ");
16698                    UserHandle.formatUid(pw, ptw.targetUid);
16699                    pw.print(": ");
16700                    TimeUtils.formatDuration(ptw.duration, pw);
16701                    pw.print(" ");
16702                    pw.println(ptw.tag);
16703                }
16704            }
16705        }
16706        if (dumpPackage == null) {
16707            pw.println("  mWakefulness="
16708                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
16709            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
16710            pw.println("  mSleeping=" + mSleeping);
16711            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
16712            if (mRunningVoice != null) {
16713                pw.println("  mRunningVoice=" + mRunningVoice);
16714                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
16715            }
16716            pw.println("  mVrController=" + mVrController);
16717        }
16718        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16719                || mOrigWaitForDebugger) {
16720            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16721                    || dumpPackage.equals(mOrigDebugApp)) {
16722                if (needSep) {
16723                    pw.println();
16724                    needSep = false;
16725                }
16726                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
16727                        + " mDebugTransient=" + mDebugTransient
16728                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
16729            }
16730        }
16731        if (mCurAppTimeTracker != null) {
16732            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
16733        }
16734        if (mMemWatchProcesses.getMap().size() > 0) {
16735            pw.println("  Mem watch processes:");
16736            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
16737                    = mMemWatchProcesses.getMap();
16738            for (int i=0; i<procs.size(); i++) {
16739                final String proc = procs.keyAt(i);
16740                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16741                for (int j=0; j<uids.size(); j++) {
16742                    if (needSep) {
16743                        pw.println();
16744                        needSep = false;
16745                    }
16746                    StringBuilder sb = new StringBuilder();
16747                    sb.append("    ").append(proc).append('/');
16748                    UserHandle.formatUid(sb, uids.keyAt(j));
16749                    Pair<Long, String> val = uids.valueAt(j);
16750                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
16751                    if (val.second != null) {
16752                        sb.append(", report to ").append(val.second);
16753                    }
16754                    pw.println(sb.toString());
16755                }
16756            }
16757            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
16758            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
16759            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
16760                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
16761        }
16762        if (mTrackAllocationApp != null) {
16763            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16764                if (needSep) {
16765                    pw.println();
16766                    needSep = false;
16767                }
16768                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
16769            }
16770        }
16771        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16772                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16773            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16774                if (needSep) {
16775                    pw.println();
16776                    needSep = false;
16777                }
16778                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16779                if (mProfilerInfo != null) {
16780                    pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16781                            mProfilerInfo.profileFd);
16782                    pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
16783                            " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16784                            " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16785                    pw.println("  mProfileType=" + mProfileType);
16786                }
16787            }
16788        }
16789        if (mNativeDebuggingApp != null) {
16790            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16791                if (needSep) {
16792                    pw.println();
16793                    needSep = false;
16794                }
16795                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16796            }
16797        }
16798        if (mAllowAppSwitchUids.size() > 0) {
16799            boolean printed = false;
16800            for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
16801                ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
16802                for (int j = 0; j < types.size(); j++) {
16803                    if (dumpPackage == null ||
16804                            UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
16805                        if (needSep) {
16806                            pw.println();
16807                            needSep = false;
16808                        }
16809                        if (!printed) {
16810                            pw.println("  mAllowAppSwitchUids:");
16811                            printed = true;
16812                        }
16813                        pw.print("    User ");
16814                        pw.print(mAllowAppSwitchUids.keyAt(i));
16815                        pw.print(": Type ");
16816                        pw.print(types.keyAt(j));
16817                        pw.print(" = ");
16818                        UserHandle.formatUid(pw, types.valueAt(j).intValue());
16819                        pw.println();
16820                    }
16821                }
16822            }
16823        }
16824        if (dumpPackage == null) {
16825            if (mAlwaysFinishActivities) {
16826                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16827            }
16828            if (mController != null) {
16829                pw.println("  mController=" + mController
16830                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16831            }
16832            if (dumpAll) {
16833                pw.println("  Total persistent processes: " + numPers);
16834                pw.println("  mProcessesReady=" + mProcessesReady
16835                        + " mSystemReady=" + mSystemReady
16836                        + " mBooted=" + mBooted
16837                        + " mFactoryTest=" + mFactoryTest);
16838                pw.println("  mBooting=" + mBooting
16839                        + " mCallFinishBooting=" + mCallFinishBooting
16840                        + " mBootAnimationComplete=" + mBootAnimationComplete);
16841                pw.print("  mLastPowerCheckUptime=");
16842                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16843                        pw.println("");
16844                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16845                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16846                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16847                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16848                        + " (" + mLruProcesses.size() + " total)"
16849                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16850                        + " mNumServiceProcs=" + mNumServiceProcs
16851                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16852                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16853                        + " mLastMemoryLevel=" + mLastMemoryLevel
16854                        + " mLastNumProcesses=" + mLastNumProcesses);
16855                long now = SystemClock.uptimeMillis();
16856                pw.print("  mLastIdleTime=");
16857                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
16858                        pw.print(" mLowRamSinceLastIdle=");
16859                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16860                        pw.println();
16861                pw.println();
16862                pw.print("  mUidChangeDispatchCount=");
16863                pw.print(mUidChangeDispatchCount);
16864                pw.println();
16865
16866                pw.println("  Slow UID dispatches:");
16867                final int N = mUidObservers.beginBroadcast();
16868                for (int i = 0; i < N; i++) {
16869                    UidObserverRegistration r =
16870                            (UidObserverRegistration) mUidObservers.getBroadcastCookie(i);
16871                    pw.print("    ");
16872                    pw.print(mUidObservers.getBroadcastItem(i).getClass().getTypeName());
16873                    pw.print(": ");
16874                    pw.print(r.mSlowDispatchCount);
16875                    pw.print(" / Max ");
16876                    pw.print(r.mMaxDispatchTime);
16877                    pw.println("ms");
16878                }
16879                mUidObservers.finishBroadcast();
16880            }
16881        }
16882        pw.println("  mForceBackgroundCheck=" + mForceBackgroundCheck);
16883    }
16884
16885    @GuardedBy("this")
16886    void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
16887        int numPers = 0;
16888
16889        final int NP = mProcessNames.getMap().size();
16890        for (int ip=0; ip<NP; ip++) {
16891            SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16892            final int NA = procs.size();
16893            for (int ia = 0; ia<NA; ia++) {
16894                ProcessRecord r = procs.valueAt(ia);
16895                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16896                    continue;
16897                }
16898                r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PROCS);
16899                if (r.persistent) {
16900                    numPers++;
16901                }
16902            }
16903        }
16904
16905        for (int i=0; i<mIsolatedProcesses.size(); i++) {
16906            ProcessRecord r = mIsolatedProcesses.valueAt(i);
16907            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16908                continue;
16909            }
16910            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ISOLATED_PROCS);
16911        }
16912
16913        for (int i=0; i<mActiveInstrumentation.size(); i++) {
16914            ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16915            if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16916                    && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16917                continue;
16918            }
16919            ai.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_INSTRUMENTATIONS);
16920        }
16921
16922        int whichAppId = getAppId(dumpPackage);
16923        for (int i=0; i<mActiveUids.size(); i++) {
16924            UidRecord uidRec = mActiveUids.valueAt(i);
16925            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
16926                continue;
16927            }
16928            uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
16929        }
16930
16931        for (int i=0; i<mValidateUids.size(); i++) {
16932            UidRecord uidRec = mValidateUids.valueAt(i);
16933            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
16934                continue;
16935            }
16936            uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VALIDATE_UIDS);
16937        }
16938
16939        if (mLruProcesses.size() > 0) {
16940            long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS);
16941            int total = mLruProcesses.size();
16942            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total);
16943            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
16944            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
16945            writeProcessOomListToProto(proto, ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, this,
16946                    mLruProcesses,false, dumpPackage);
16947            proto.end(lruToken);
16948        }
16949
16950        if (dumpPackage != null) {
16951            synchronized (mPidsSelfLocked) {
16952                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16953                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16954                    if (!r.pkgList.containsKey(dumpPackage)) {
16955                        continue;
16956                    }
16957                    r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PIDS_SELF_LOCKED);
16958                }
16959            }
16960        }
16961
16962        if (mImportantProcesses.size() > 0) {
16963            synchronized (mPidsSelfLocked) {
16964                for (int i=0; i<mImportantProcesses.size(); i++) {
16965                    ImportanceToken it = mImportantProcesses.valueAt(i);
16966                    ProcessRecord r = mPidsSelfLocked.get(it.pid);
16967                    if (dumpPackage != null && (r == null
16968                            || !r.pkgList.containsKey(dumpPackage))) {
16969                        continue;
16970                    }
16971                    it.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.IMPORTANT_PROCS);
16972                }
16973            }
16974        }
16975
16976        for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
16977            ProcessRecord r = mPersistentStartingProcesses.get(i);
16978            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16979                continue;
16980            }
16981            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PERSISTENT_STARTING_PROCS);
16982        }
16983
16984        for (int i=0; i<mRemovedProcesses.size(); i++) {
16985            ProcessRecord r = mRemovedProcesses.get(i);
16986            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16987                continue;
16988            }
16989            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.REMOVED_PROCS);
16990        }
16991
16992        for (int i=0; i<mProcessesOnHold.size(); i++) {
16993            ProcessRecord r = mProcessesOnHold.get(i);
16994            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16995                continue;
16996            }
16997            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.ON_HOLD_PROCS);
16998        }
16999
17000        writeProcessesToGcToProto(proto, ActivityManagerServiceDumpProcessesProto.GC_PROCS, dumpPackage);
17001        mAppErrors.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.APP_ERRORS, dumpPackage);
17002
17003        if (dumpPackage == null) {
17004            mUserController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER);
17005            getGlobalConfiguration().writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION);
17006            proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
17007        }
17008
17009        if (mHomeProcess != null && (dumpPackage == null
17010                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
17011            mHomeProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HOME_PROC);
17012        }
17013
17014        if (mPreviousProcess != null && (dumpPackage == null
17015                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
17016            mPreviousProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC);
17017            proto.write(ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
17018        }
17019
17020        if (mHeavyWeightProcess != null && (dumpPackage == null
17021                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
17022            mHeavyWeightProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC);
17023        }
17024
17025        for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
17026            String pkg = entry.getKey();
17027            int mode = entry.getValue();
17028            if (dumpPackage == null || dumpPackage.equals(pkg)) {
17029                long compatToken = proto.start(ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES);
17030                proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
17031                proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE, mode);
17032                proto.end(compatToken);
17033            }
17034        }
17035
17036        final int NI = mUidObservers.getRegisteredCallbackCount();
17037        for (int i=0; i<NI; i++) {
17038            final UidObserverRegistration reg = (UidObserverRegistration)
17039                    mUidObservers.getRegisteredCallbackCookie(i);
17040            if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
17041                reg.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
17042            }
17043        }
17044
17045        for (int v : mDeviceIdleWhitelist) {
17046            proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_WHITELIST, v);
17047        }
17048
17049        for (int v : mDeviceIdleTempWhitelist) {
17050            proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
17051        }
17052
17053        if (mPendingTempWhitelist.size() > 0) {
17054            for (int i=0; i < mPendingTempWhitelist.size(); i++) {
17055                mPendingTempWhitelist.valueAt(i).writeToProto(proto,
17056                        ActivityManagerServiceDumpProcessesProto.PENDING_TEMP_WHITELIST);
17057            }
17058        }
17059
17060        if (dumpPackage == null) {
17061            final long sleepToken = proto.start(ActivityManagerServiceDumpProcessesProto.SLEEP_STATUS);
17062            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.WAKEFULNESS,
17063                    PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
17064            for (SleepToken st : mStackSupervisor.mSleepTokens) {
17065                proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
17066            }
17067            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
17068            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
17069            proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
17070            proto.end(sleepToken);
17071
17072            if (mRunningVoice != null) {
17073                final long vrToken = proto.start(ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
17074                proto.write(ActivityManagerServiceDumpProcessesProto.VoiceProto.SESSION, mRunningVoice.toString());
17075                mVoiceWakeLock.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VoiceProto.WAKELOCK);
17076                proto.end(vrToken);
17077            }
17078
17079            mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
17080        }
17081
17082        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
17083                || mOrigWaitForDebugger) {
17084            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
17085                    || dumpPackage.equals(mOrigDebugApp)) {
17086                final long debugAppToken = proto.start(ActivityManagerServiceDumpProcessesProto.DEBUG);
17087                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
17088                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
17089                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
17090                proto.write(ActivityManagerServiceDumpProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
17091                proto.end(debugAppToken);
17092            }
17093        }
17094
17095        if (mCurAppTimeTracker != null) {
17096            mCurAppTimeTracker.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER, true);
17097        }
17098
17099        if (mMemWatchProcesses.getMap().size() > 0) {
17100            final long token = proto.start(ActivityManagerServiceDumpProcessesProto.MEM_WATCH_PROCESSES);
17101            ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
17102            for (int i=0; i<procs.size(); i++) {
17103                final String proc = procs.keyAt(i);
17104                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
17105                final long ptoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.PROCS);
17106                proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.NAME, proc);
17107                for (int j=0; j<uids.size(); j++) {
17108                    final long utoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MEM_STATS);
17109                    Pair<Long, String> val = uids.valueAt(j);
17110                    proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
17111                    proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
17112                            DebugUtils.sizeValueToString(val.first, new StringBuilder()));
17113                    proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
17114                    proto.end(utoken);
17115                }
17116                proto.end(ptoken);
17117            }
17118
17119            final long dtoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.DUMP);
17120            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
17121            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
17122            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
17123            proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
17124            proto.end(dtoken);
17125
17126            proto.end(token);
17127        }
17128
17129        if (mTrackAllocationApp != null) {
17130            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
17131                proto.write(ActivityManagerServiceDumpProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
17132            }
17133        }
17134
17135        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
17136                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
17137            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
17138                final long token = proto.start(ActivityManagerServiceDumpProcessesProto.PROFILE);
17139                proto.write(ActivityManagerServiceDumpProcessesProto.Profile.APP_NAME, mProfileApp);
17140                mProfileProc.writeToProto(proto,ActivityManagerServiceDumpProcessesProto.Profile.PROC);
17141                if (mProfilerInfo != null) {
17142                    mProfilerInfo.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Profile.INFO);
17143                    proto.write(ActivityManagerServiceDumpProcessesProto.Profile.TYPE, mProfileType);
17144                }
17145                proto.end(token);
17146            }
17147        }
17148
17149        if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
17150            proto.write(ActivityManagerServiceDumpProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
17151        }
17152
17153        if (dumpPackage == null) {
17154            proto.write(ActivityManagerServiceDumpProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
17155            if (mController != null) {
17156                final long token = proto.start(ActivityManagerServiceDumpProcessesProto.CONTROLLER);
17157                proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mController.toString());
17158                proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
17159                proto.end(token);
17160            }
17161            proto.write(ActivityManagerServiceDumpProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
17162            proto.write(ActivityManagerServiceDumpProcessesProto.PROCESSES_READY, mProcessesReady);
17163            proto.write(ActivityManagerServiceDumpProcessesProto.SYSTEM_READY, mSystemReady);
17164            proto.write(ActivityManagerServiceDumpProcessesProto.BOOTED, mBooted);
17165            proto.write(ActivityManagerServiceDumpProcessesProto.FACTORY_TEST, mFactoryTest);
17166            proto.write(ActivityManagerServiceDumpProcessesProto.BOOTING, mBooting);
17167            proto.write(ActivityManagerServiceDumpProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
17168            proto.write(ActivityManagerServiceDumpProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
17169            proto.write(ActivityManagerServiceDumpProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
17170            mStackSupervisor.mGoingToSleep.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP);
17171            mStackSupervisor.mLaunchingActivity.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY);
17172            proto.write(ActivityManagerServiceDumpProcessesProto.ADJ_SEQ, mAdjSeq);
17173            proto.write(ActivityManagerServiceDumpProcessesProto.LRU_SEQ, mLruSeq);
17174            proto.write(ActivityManagerServiceDumpProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
17175            proto.write(ActivityManagerServiceDumpProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
17176            proto.write(ActivityManagerServiceDumpProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
17177            proto.write(ActivityManagerServiceDumpProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
17178            proto.write(ActivityManagerServiceDumpProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
17179            proto.write(ActivityManagerServiceDumpProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
17180            long now = SystemClock.uptimeMillis();
17181            ProtoUtils.toDuration(proto, ActivityManagerServiceDumpProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
17182            proto.write(ActivityManagerServiceDumpProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
17183        }
17184
17185    }
17186
17187    void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
17188        if (mProcessesToGc.size() > 0) {
17189            long now = SystemClock.uptimeMillis();
17190            for (int i=0; i<mProcessesToGc.size(); i++) {
17191                ProcessRecord r = mProcessesToGc.get(i);
17192                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17193                    continue;
17194                }
17195                final long token = proto.start(fieldId);
17196                r.writeToProto(proto, ProcessToGcProto.PROC);
17197                proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
17198                proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
17199                proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
17200                proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory);
17201                proto.end(token);
17202            }
17203        }
17204    }
17205
17206    boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) {
17207        if (mProcessesToGc.size() > 0) {
17208            boolean printed = false;
17209            long now = SystemClock.uptimeMillis();
17210            for (int i=0; i<mProcessesToGc.size(); i++) {
17211                ProcessRecord proc = mProcessesToGc.get(i);
17212                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
17213                    continue;
17214                }
17215                if (!printed) {
17216                    if (needSep) pw.println();
17217                    needSep = true;
17218                    pw.println("  Processes that are waiting to GC:");
17219                    printed = true;
17220                }
17221                pw.print("    Process "); pw.println(proc);
17222                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
17223                        pw.print(", last gced=");
17224                        pw.print(now-proc.lastRequestedGc);
17225                        pw.print(" ms ago, last lowMem=");
17226                        pw.print(now-proc.lastLowMemory);
17227                        pw.println(" ms ago");
17228
17229            }
17230        }
17231        return needSep;
17232    }
17233
17234    void printOomLevel(PrintWriter pw, String name, int adj) {
17235        pw.print("    ");
17236        if (adj >= 0) {
17237            pw.print(' ');
17238            if (adj < 10) pw.print(' ');
17239        } else {
17240            if (adj > -10) pw.print(' ');
17241        }
17242        pw.print(adj);
17243        pw.print(": ");
17244        pw.print(name);
17245        pw.print(" (");
17246        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
17247        pw.println(")");
17248    }
17249
17250    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17251            int opti, boolean dumpAll) {
17252        boolean needSep = false;
17253
17254        if (mLruProcesses.size() > 0) {
17255            if (needSep) pw.println();
17256            needSep = true;
17257            pw.println("  OOM levels:");
17258            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
17259            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
17260            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
17261            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
17262            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
17263            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
17264            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
17265            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
17266            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
17267            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
17268            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
17269            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
17270            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
17271            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
17272
17273            if (needSep) pw.println();
17274            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
17275                    pw.print(" total, non-act at ");
17276                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
17277                    pw.print(", non-svc at ");
17278                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
17279                    pw.println("):");
17280            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
17281            needSep = true;
17282        }
17283
17284        dumpProcessesToGc(pw, needSep, null);
17285
17286        pw.println();
17287        pw.println("  mHomeProcess: " + mHomeProcess);
17288        pw.println("  mPreviousProcess: " + mPreviousProcess);
17289        if (mHeavyWeightProcess != null) {
17290            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
17291        }
17292
17293        return true;
17294    }
17295
17296    /**
17297     * There are three ways to call this:
17298     *  - no provider specified: dump all the providers
17299     *  - a flattened component name that matched an existing provider was specified as the
17300     *    first arg: dump that one provider
17301     *  - the first arg isn't the flattened component name of an existing provider:
17302     *    dump all providers whose component contains the first arg as a substring
17303     */
17304    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17305            int opti, boolean dumpAll) {
17306        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
17307    }
17308
17309    /**
17310     * Similar to the dumpProvider, but only dumps the first matching provider.
17311     * The provider is responsible for dumping as proto.
17312     */
17313    protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
17314            String[] args) {
17315        return mProviderMap.dumpProviderProto(fd, pw, name, args);
17316    }
17317
17318    static class ItemMatcher {
17319        ArrayList<ComponentName> components;
17320        ArrayList<String> strings;
17321        ArrayList<Integer> objects;
17322        boolean all;
17323
17324        ItemMatcher() {
17325            all = true;
17326        }
17327
17328        void build(String name) {
17329            ComponentName componentName = ComponentName.unflattenFromString(name);
17330            if (componentName != null) {
17331                if (components == null) {
17332                    components = new ArrayList<ComponentName>();
17333                }
17334                components.add(componentName);
17335                all = false;
17336            } else {
17337                int objectId = 0;
17338                // Not a '/' separated full component name; maybe an object ID?
17339                try {
17340                    objectId = Integer.parseInt(name, 16);
17341                    if (objects == null) {
17342                        objects = new ArrayList<Integer>();
17343                    }
17344                    objects.add(objectId);
17345                    all = false;
17346                } catch (RuntimeException e) {
17347                    // Not an integer; just do string match.
17348                    if (strings == null) {
17349                        strings = new ArrayList<String>();
17350                    }
17351                    strings.add(name);
17352                    all = false;
17353                }
17354            }
17355        }
17356
17357        int build(String[] args, int opti) {
17358            for (; opti<args.length; opti++) {
17359                String name = args[opti];
17360                if ("--".equals(name)) {
17361                    return opti+1;
17362                }
17363                build(name);
17364            }
17365            return opti;
17366        }
17367
17368        boolean match(Object object, ComponentName comp) {
17369            if (all) {
17370                return true;
17371            }
17372            if (components != null) {
17373                for (int i=0; i<components.size(); i++) {
17374                    if (components.get(i).equals(comp)) {
17375                        return true;
17376                    }
17377                }
17378            }
17379            if (objects != null) {
17380                for (int i=0; i<objects.size(); i++) {
17381                    if (System.identityHashCode(object) == objects.get(i)) {
17382                        return true;
17383                    }
17384                }
17385            }
17386            if (strings != null) {
17387                String flat = comp.flattenToString();
17388                for (int i=0; i<strings.size(); i++) {
17389                    if (flat.contains(strings.get(i))) {
17390                        return true;
17391                    }
17392                }
17393            }
17394            return false;
17395        }
17396    }
17397
17398    /**
17399     * There are three things that cmd can be:
17400     *  - a flattened component name that matches an existing activity
17401     *  - the cmd arg isn't the flattened component name of an existing activity:
17402     *    dump all activity whose component contains the cmd as a substring
17403     *  - A hex number of the ActivityRecord object instance.
17404     *
17405     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
17406     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
17407     */
17408    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17409            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
17410        ArrayList<ActivityRecord> activities;
17411
17412        synchronized (this) {
17413            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
17414                    dumpFocusedStackOnly);
17415        }
17416
17417        if (activities.size() <= 0) {
17418            return false;
17419        }
17420
17421        String[] newArgs = new String[args.length - opti];
17422        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
17423
17424        TaskRecord lastTask = null;
17425        boolean needSep = false;
17426        for (int i=activities.size()-1; i>=0; i--) {
17427            ActivityRecord r = activities.get(i);
17428            if (needSep) {
17429                pw.println();
17430            }
17431            needSep = true;
17432            synchronized (this) {
17433                final TaskRecord task = r.getTask();
17434                if (lastTask != task) {
17435                    lastTask = task;
17436                    pw.print("TASK "); pw.print(lastTask.affinity);
17437                            pw.print(" id="); pw.print(lastTask.taskId);
17438                            pw.print(" userId="); pw.println(lastTask.userId);
17439                    if (dumpAll) {
17440                        lastTask.dump(pw, "  ");
17441                    }
17442                }
17443            }
17444            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
17445        }
17446        return true;
17447    }
17448
17449    /**
17450     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
17451     * there is a thread associated with the activity.
17452     */
17453    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
17454            final ActivityRecord r, String[] args, boolean dumpAll) {
17455        String innerPrefix = prefix + "  ";
17456        synchronized (this) {
17457            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
17458                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
17459                    pw.print(" pid=");
17460                    if (r.app != null) pw.println(r.app.pid);
17461                    else pw.println("(not running)");
17462            if (dumpAll) {
17463                r.dump(pw, innerPrefix);
17464            }
17465        }
17466        if (r.app != null && r.app.thread != null) {
17467            // flush anything that is already in the PrintWriter since the thread is going
17468            // to write to the file descriptor directly
17469            pw.flush();
17470            try {
17471                TransferPipe tp = new TransferPipe();
17472                try {
17473                    r.app.thread.dumpActivity(tp.getWriteFd(),
17474                            r.appToken, innerPrefix, args);
17475                    tp.go(fd);
17476                } finally {
17477                    tp.kill();
17478                }
17479            } catch (IOException e) {
17480                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
17481            } catch (RemoteException e) {
17482                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
17483            }
17484        }
17485    }
17486
17487    void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
17488        if (mRegisteredReceivers.size() > 0) {
17489            Iterator it = mRegisteredReceivers.values().iterator();
17490            while (it.hasNext()) {
17491                ReceiverList r = (ReceiverList)it.next();
17492                r.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_LIST);
17493            }
17494        }
17495        mReceiverResolver.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.RECEIVER_RESOLVER);
17496        for (BroadcastQueue q : mBroadcastQueues) {
17497            q.writeToProto(proto, ActivityManagerServiceDumpBroadcastsProto.BROADCAST_QUEUE);
17498        }
17499        for (int user=0; user<mStickyBroadcasts.size(); user++) {
17500            long token = proto.start(ActivityManagerServiceDumpBroadcastsProto.STICKY_BROADCASTS);
17501            proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
17502            for (Map.Entry<String, ArrayList<Intent>> ent
17503                    : mStickyBroadcasts.valueAt(user).entrySet()) {
17504                long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
17505                proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
17506                for (Intent intent : ent.getValue()) {
17507                    intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
17508                            false, true, true, false);
17509                }
17510                proto.end(actionToken);
17511            }
17512            proto.end(token);
17513        }
17514
17515        long handlerToken = proto.start(ActivityManagerServiceDumpBroadcastsProto.HANDLER);
17516        proto.write(ActivityManagerServiceDumpBroadcastsProto.MainHandler.HANDLER, mHandler.toString());
17517        mHandler.getLooper().writeToProto(proto,
17518            ActivityManagerServiceDumpBroadcastsProto.MainHandler.LOOPER);
17519        proto.end(handlerToken);
17520    }
17521
17522    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17523            int opti, boolean dumpAll, String dumpPackage) {
17524        boolean needSep = false;
17525        boolean onlyHistory = false;
17526        boolean printedAnything = false;
17527
17528        if ("history".equals(dumpPackage)) {
17529            if (opti < args.length && "-s".equals(args[opti])) {
17530                dumpAll = false;
17531            }
17532            onlyHistory = true;
17533            dumpPackage = null;
17534        }
17535
17536        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
17537        if (!onlyHistory && dumpAll) {
17538            if (mRegisteredReceivers.size() > 0) {
17539                boolean printed = false;
17540                Iterator it = mRegisteredReceivers.values().iterator();
17541                while (it.hasNext()) {
17542                    ReceiverList r = (ReceiverList)it.next();
17543                    if (dumpPackage != null && (r.app == null ||
17544                            !dumpPackage.equals(r.app.info.packageName))) {
17545                        continue;
17546                    }
17547                    if (!printed) {
17548                        pw.println("  Registered Receivers:");
17549                        needSep = true;
17550                        printed = true;
17551                        printedAnything = true;
17552                    }
17553                    pw.print("  * "); pw.println(r);
17554                    r.dump(pw, "    ");
17555                }
17556            }
17557
17558            if (mReceiverResolver.dump(pw, needSep ?
17559                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
17560                    "    ", dumpPackage, false, false)) {
17561                needSep = true;
17562                printedAnything = true;
17563            }
17564        }
17565
17566        for (BroadcastQueue q : mBroadcastQueues) {
17567            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
17568            printedAnything |= needSep;
17569        }
17570
17571        needSep = true;
17572
17573        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
17574            for (int user=0; user<mStickyBroadcasts.size(); user++) {
17575                if (needSep) {
17576                    pw.println();
17577                }
17578                needSep = true;
17579                printedAnything = true;
17580                pw.print("  Sticky broadcasts for user ");
17581                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
17582                StringBuilder sb = new StringBuilder(128);
17583                for (Map.Entry<String, ArrayList<Intent>> ent
17584                        : mStickyBroadcasts.valueAt(user).entrySet()) {
17585                    pw.print("  * Sticky action "); pw.print(ent.getKey());
17586                    if (dumpAll) {
17587                        pw.println(":");
17588                        ArrayList<Intent> intents = ent.getValue();
17589                        final int N = intents.size();
17590                        for (int i=0; i<N; i++) {
17591                            sb.setLength(0);
17592                            sb.append("    Intent: ");
17593                            intents.get(i).toShortString(sb, false, true, false, false);
17594                            pw.println(sb.toString());
17595                            Bundle bundle = intents.get(i).getExtras();
17596                            if (bundle != null) {
17597                                pw.print("      ");
17598                                pw.println(bundle.toString());
17599                            }
17600                        }
17601                    } else {
17602                        pw.println("");
17603                    }
17604                }
17605            }
17606        }
17607
17608        if (!onlyHistory && dumpAll) {
17609            pw.println();
17610            for (BroadcastQueue queue : mBroadcastQueues) {
17611                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
17612                        + queue.mBroadcastsScheduled);
17613            }
17614            pw.println("  mHandler:");
17615            mHandler.dump(new PrintWriterPrinter(pw), "    ");
17616            needSep = true;
17617            printedAnything = true;
17618        }
17619
17620        if (!printedAnything) {
17621            pw.println("  (nothing)");
17622        }
17623    }
17624
17625    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17626            int opti, boolean dumpAll, String dumpPackage) {
17627        if (mCurBroadcastStats == null) {
17628            return;
17629        }
17630
17631        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
17632        final long now = SystemClock.elapsedRealtime();
17633        if (mLastBroadcastStats != null) {
17634            pw.print("  Last stats (from ");
17635            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
17636            pw.print(" to ");
17637            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
17638            pw.print(", ");
17639            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
17640                    - mLastBroadcastStats.mStartUptime, pw);
17641            pw.println(" uptime):");
17642            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17643                pw.println("    (nothing)");
17644            }
17645            pw.println();
17646        }
17647        pw.print("  Current stats (from ");
17648        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
17649        pw.print(" to now, ");
17650        TimeUtils.formatDuration(SystemClock.uptimeMillis()
17651                - mCurBroadcastStats.mStartUptime, pw);
17652        pw.println(" uptime):");
17653        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17654            pw.println("    (nothing)");
17655        }
17656    }
17657
17658    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17659            int opti, boolean fullCheckin, String dumpPackage) {
17660        if (mCurBroadcastStats == null) {
17661            return;
17662        }
17663
17664        if (mLastBroadcastStats != null) {
17665            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17666            if (fullCheckin) {
17667                mLastBroadcastStats = null;
17668                return;
17669            }
17670        }
17671        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17672        if (fullCheckin) {
17673            mCurBroadcastStats = null;
17674        }
17675    }
17676
17677    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17678            int opti, boolean dumpAll, String dumpPackage) {
17679        boolean needSep;
17680        boolean printedAnything = false;
17681
17682        ItemMatcher matcher = new ItemMatcher();
17683        matcher.build(args, opti);
17684
17685        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
17686
17687        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
17688        printedAnything |= needSep;
17689
17690        if (mLaunchingProviders.size() > 0) {
17691            boolean printed = false;
17692            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
17693                ContentProviderRecord r = mLaunchingProviders.get(i);
17694                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
17695                    continue;
17696                }
17697                if (!printed) {
17698                    if (needSep) pw.println();
17699                    needSep = true;
17700                    pw.println("  Launching content providers:");
17701                    printed = true;
17702                    printedAnything = true;
17703                }
17704                pw.print("  Launching #"); pw.print(i); pw.print(": ");
17705                        pw.println(r);
17706            }
17707        }
17708
17709        if (!printedAnything) {
17710            pw.println("  (nothing)");
17711        }
17712    }
17713
17714    @GuardedBy("this")
17715    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17716            int opti, boolean dumpAll, String dumpPackage) {
17717        boolean needSep = false;
17718        boolean printedAnything = false;
17719
17720        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
17721
17722        if (mGrantedUriPermissions.size() > 0) {
17723            boolean printed = false;
17724            int dumpUid = -2;
17725            if (dumpPackage != null) {
17726                try {
17727                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
17728                            MATCH_ANY_USER, 0);
17729                } catch (NameNotFoundException e) {
17730                    dumpUid = -1;
17731                }
17732            }
17733            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
17734                int uid = mGrantedUriPermissions.keyAt(i);
17735                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
17736                    continue;
17737                }
17738                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
17739                if (!printed) {
17740                    if (needSep) pw.println();
17741                    needSep = true;
17742                    pw.println("  Granted Uri Permissions:");
17743                    printed = true;
17744                    printedAnything = true;
17745                }
17746                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
17747                for (UriPermission perm : perms.values()) {
17748                    pw.print("    "); pw.println(perm);
17749                    if (dumpAll) {
17750                        perm.dump(pw, "      ");
17751                    }
17752                }
17753            }
17754        }
17755
17756        if (!printedAnything) {
17757            pw.println("  (nothing)");
17758        }
17759    }
17760
17761    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17762            int opti, boolean dumpAll, String dumpPackage) {
17763        boolean printed = false;
17764
17765        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
17766
17767        if (mIntentSenderRecords.size() > 0) {
17768            // Organize these by package name, so they are easier to read.
17769            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
17770            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
17771            final Iterator<WeakReference<PendingIntentRecord>> it
17772                    = mIntentSenderRecords.values().iterator();
17773            while (it.hasNext()) {
17774                WeakReference<PendingIntentRecord> ref = it.next();
17775                PendingIntentRecord rec = ref != null ? ref.get() : null;
17776                if (rec == null) {
17777                    weakRefs.add(ref);
17778                    continue;
17779                }
17780                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
17781                    continue;
17782                }
17783                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
17784                if (list == null) {
17785                    list = new ArrayList<>();
17786                    byPackage.put(rec.key.packageName, list);
17787                }
17788                list.add(rec);
17789            }
17790            for (int i = 0; i < byPackage.size(); i++) {
17791                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
17792                printed = true;
17793                pw.print("  * "); pw.print(byPackage.keyAt(i));
17794                pw.print(": "); pw.print(intents.size()); pw.println(" items");
17795                for (int j = 0; j < intents.size(); j++) {
17796                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
17797                    if (dumpAll) {
17798                        intents.get(j).dump(pw, "      ");
17799                    }
17800                }
17801            }
17802            if (weakRefs.size() > 0) {
17803                printed = true;
17804                pw.println("  * WEAK REFS:");
17805                for (int i = 0; i < weakRefs.size(); i++) {
17806                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
17807                }
17808            }
17809        }
17810
17811        if (!printed) {
17812            pw.println("  (nothing)");
17813        }
17814    }
17815
17816    private static final int dumpProcessList(PrintWriter pw,
17817            ActivityManagerService service, List list,
17818            String prefix, String normalLabel, String persistentLabel,
17819            String dumpPackage) {
17820        int numPers = 0;
17821        final int N = list.size()-1;
17822        for (int i=N; i>=0; i--) {
17823            ProcessRecord r = (ProcessRecord)list.get(i);
17824            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17825                continue;
17826            }
17827            pw.println(String.format("%s%s #%2d: %s",
17828                    prefix, (r.persistent ? persistentLabel : normalLabel),
17829                    i, r.toString()));
17830            if (r.persistent) {
17831                numPers++;
17832            }
17833        }
17834        return numPers;
17835    }
17836
17837    private static final ArrayList<Pair<ProcessRecord, Integer>>
17838        sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) {
17839        ArrayList<Pair<ProcessRecord, Integer>> list
17840                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
17841        for (int i=0; i<origList.size(); i++) {
17842            ProcessRecord r = origList.get(i);
17843            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17844                continue;
17845            }
17846            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
17847        }
17848
17849        Comparator<Pair<ProcessRecord, Integer>> comparator
17850                = new Comparator<Pair<ProcessRecord, Integer>>() {
17851            @Override
17852            public int compare(Pair<ProcessRecord, Integer> object1,
17853                    Pair<ProcessRecord, Integer> object2) {
17854                if (object1.first.setAdj != object2.first.setAdj) {
17855                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
17856                }
17857                if (object1.first.setProcState != object2.first.setProcState) {
17858                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
17859                }
17860                if (object1.second.intValue() != object2.second.intValue()) {
17861                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
17862                }
17863                return 0;
17864            }
17865        };
17866
17867        Collections.sort(list, comparator);
17868        return list;
17869    }
17870
17871    private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
17872            ActivityManagerService service, List<ProcessRecord> origList,
17873            boolean inclDetails, String dumpPackage) {
17874        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
17875        if (list.isEmpty()) return false;
17876
17877        final long curUptime = SystemClock.uptimeMillis();
17878
17879        for (int i = list.size() - 1; i >= 0; i--) {
17880            ProcessRecord r = list.get(i).first;
17881            long token = proto.start(fieldId);
17882            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
17883            proto.write(ProcessOomProto.PERSISTENT, r.persistent);
17884            proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
17885            proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
17886            int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
17887            switch (r.setSchedGroup) {
17888                case ProcessList.SCHED_GROUP_BACKGROUND:
17889                    schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
17890                    break;
17891                case ProcessList.SCHED_GROUP_DEFAULT:
17892                    schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
17893                    break;
17894                case ProcessList.SCHED_GROUP_TOP_APP:
17895                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
17896                    break;
17897                case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
17898                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
17899                    break;
17900            }
17901            if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
17902                proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
17903            }
17904            if (r.foregroundActivities) {
17905                proto.write(ProcessOomProto.ACTIVITIES, true);
17906            } else if (r.foregroundServices) {
17907                proto.write(ProcessOomProto.SERVICES, true);
17908            }
17909            proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
17910            proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
17911            r.writeToProto(proto, ProcessOomProto.PROC);
17912            proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
17913            if (r.adjSource != null || r.adjTarget != null) {
17914                if (r.adjTarget instanceof  ComponentName) {
17915                    ComponentName cn = (ComponentName) r.adjTarget;
17916                    cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
17917                } else if (r.adjTarget != null) {
17918                    proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
17919                }
17920                if (r.adjSource instanceof ProcessRecord) {
17921                    ProcessRecord p = (ProcessRecord) r.adjSource;
17922                    p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
17923                } else if (r.adjSource != null) {
17924                    proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
17925                }
17926            }
17927            if (inclDetails) {
17928                long detailToken = proto.start(ProcessOomProto.DETAIL);
17929                proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
17930                proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
17931                proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
17932                proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
17933                proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
17934                proto.write(ProcessOomProto.Detail.CURRENT_STATE,
17935                        ProcessList.makeProcStateProtoEnum(r.curProcState));
17936                proto.write(ProcessOomProto.Detail.SET_STATE,
17937                        ProcessList.makeProcStateProtoEnum(r.setProcState));
17938                proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
17939                        r.lastPss*1024, new StringBuilder()));
17940                proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
17941                        r.lastSwapPss*1024, new StringBuilder()));
17942                proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
17943                        r.lastCachedPss*1024, new StringBuilder()));
17944                proto.write(ProcessOomProto.Detail.CACHED, r.cached);
17945                proto.write(ProcessOomProto.Detail.EMPTY, r.empty);
17946                proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient);
17947
17948                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
17949                    if (r.lastCpuTime != 0) {
17950                        long uptimeSince = curUptime - service.mLastPowerCheckUptime;
17951                        long timeUsed = r.curCpuTime - r.lastCpuTime;
17952                        long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
17953                        proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
17954                        proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
17955                        proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
17956                                (100.0*timeUsed)/uptimeSince);
17957                        proto.end(cpuTimeToken);
17958                    }
17959                }
17960                proto.end(detailToken);
17961            }
17962            proto.end(token);
17963        }
17964
17965        return true;
17966    }
17967
17968    private static final boolean dumpProcessOomList(PrintWriter pw,
17969            ActivityManagerService service, List<ProcessRecord> origList,
17970            String prefix, String normalLabel, String persistentLabel,
17971            boolean inclDetails, String dumpPackage) {
17972
17973        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
17974        if (list.isEmpty()) return false;
17975
17976        final long curUptime = SystemClock.uptimeMillis();
17977        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
17978
17979        for (int i=list.size()-1; i>=0; i--) {
17980            ProcessRecord r = list.get(i).first;
17981            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
17982            char schedGroup;
17983            switch (r.setSchedGroup) {
17984                case ProcessList.SCHED_GROUP_BACKGROUND:
17985                    schedGroup = 'B';
17986                    break;
17987                case ProcessList.SCHED_GROUP_DEFAULT:
17988                    schedGroup = 'F';
17989                    break;
17990                case ProcessList.SCHED_GROUP_TOP_APP:
17991                    schedGroup = 'T';
17992                    break;
17993                default:
17994                    schedGroup = '?';
17995                    break;
17996            }
17997            char foreground;
17998            if (r.foregroundActivities) {
17999                foreground = 'A';
18000            } else if (r.foregroundServices) {
18001                foreground = 'S';
18002            } else {
18003                foreground = ' ';
18004            }
18005            String procState = ProcessList.makeProcStateString(r.curProcState);
18006            pw.print(prefix);
18007            pw.print(r.persistent ? persistentLabel : normalLabel);
18008            pw.print(" #");
18009            int num = (origList.size()-1)-list.get(i).second;
18010            if (num < 10) pw.print(' ');
18011            pw.print(num);
18012            pw.print(": ");
18013            pw.print(oomAdj);
18014            pw.print(' ');
18015            pw.print(schedGroup);
18016            pw.print('/');
18017            pw.print(foreground);
18018            pw.print('/');
18019            pw.print(procState);
18020            pw.print(" trm:");
18021            if (r.trimMemoryLevel < 10) pw.print(' ');
18022            pw.print(r.trimMemoryLevel);
18023            pw.print(' ');
18024            pw.print(r.toShortString());
18025            pw.print(" (");
18026            pw.print(r.adjType);
18027            pw.println(')');
18028            if (r.adjSource != null || r.adjTarget != null) {
18029                pw.print(prefix);
18030                pw.print("    ");
18031                if (r.adjTarget instanceof ComponentName) {
18032                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
18033                } else if (r.adjTarget != null) {
18034                    pw.print(r.adjTarget.toString());
18035                } else {
18036                    pw.print("{null}");
18037                }
18038                pw.print("<=");
18039                if (r.adjSource instanceof ProcessRecord) {
18040                    pw.print("Proc{");
18041                    pw.print(((ProcessRecord)r.adjSource).toShortString());
18042                    pw.println("}");
18043                } else if (r.adjSource != null) {
18044                    pw.println(r.adjSource.toString());
18045                } else {
18046                    pw.println("{null}");
18047                }
18048            }
18049            if (inclDetails) {
18050                pw.print(prefix);
18051                pw.print("    ");
18052                pw.print("oom: max="); pw.print(r.maxAdj);
18053                pw.print(" curRaw="); pw.print(r.curRawAdj);
18054                pw.print(" setRaw="); pw.print(r.setRawAdj);
18055                pw.print(" cur="); pw.print(r.curAdj);
18056                pw.print(" set="); pw.println(r.setAdj);
18057                pw.print(prefix);
18058                pw.print("    ");
18059                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
18060                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
18061                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
18062                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
18063                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
18064                pw.println();
18065                pw.print(prefix);
18066                pw.print("    ");
18067                pw.print("cached="); pw.print(r.cached);
18068                pw.print(" empty="); pw.print(r.empty);
18069                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
18070
18071                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
18072                    if (r.lastCpuTime != 0) {
18073                        long timeUsed = r.curCpuTime - r.lastCpuTime;
18074                        pw.print(prefix);
18075                        pw.print("    ");
18076                        pw.print("run cpu over ");
18077                        TimeUtils.formatDuration(uptimeSince, pw);
18078                        pw.print(" used ");
18079                        TimeUtils.formatDuration(timeUsed, pw);
18080                        pw.print(" (");
18081                        pw.print((timeUsed*100)/uptimeSince);
18082                        pw.println("%)");
18083                    }
18084                }
18085            }
18086        }
18087        return true;
18088    }
18089
18090    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
18091            String[] args) {
18092        ArrayList<ProcessRecord> procs;
18093        synchronized (this) {
18094            if (args != null && args.length > start
18095                    && args[start].charAt(0) != '-') {
18096                procs = new ArrayList<ProcessRecord>();
18097                int pid = -1;
18098                try {
18099                    pid = Integer.parseInt(args[start]);
18100                } catch (NumberFormatException e) {
18101                }
18102                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18103                    ProcessRecord proc = mLruProcesses.get(i);
18104                    if (proc.pid > 0 && proc.pid == pid) {
18105                        procs.add(proc);
18106                    } else if (allPkgs && proc.pkgList != null
18107                            && proc.pkgList.containsKey(args[start])) {
18108                        procs.add(proc);
18109                    } else if (proc.processName.equals(args[start])) {
18110                        procs.add(proc);
18111                    }
18112                }
18113                if (procs.size() <= 0) {
18114                    return null;
18115                }
18116            } else {
18117                procs = new ArrayList<ProcessRecord>(mLruProcesses);
18118            }
18119        }
18120        return procs;
18121    }
18122
18123    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
18124            PrintWriter pw, String[] args) {
18125        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18126        if (procs == null) {
18127            pw.println("No process found for: " + args[0]);
18128            return;
18129        }
18130
18131        long uptime = SystemClock.uptimeMillis();
18132        long realtime = SystemClock.elapsedRealtime();
18133        pw.println("Applications Graphics Acceleration Info:");
18134        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18135
18136        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18137            ProcessRecord r = procs.get(i);
18138            if (r.thread != null) {
18139                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
18140                pw.flush();
18141                try {
18142                    TransferPipe tp = new TransferPipe();
18143                    try {
18144                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
18145                        tp.go(fd);
18146                    } finally {
18147                        tp.kill();
18148                    }
18149                } catch (IOException e) {
18150                    pw.println("Failure while dumping the app: " + r);
18151                    pw.flush();
18152                } catch (RemoteException e) {
18153                    pw.println("Got a RemoteException while dumping the app " + r);
18154                    pw.flush();
18155                }
18156            }
18157        }
18158    }
18159
18160    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
18161        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18162        if (procs == null) {
18163            pw.println("No process found for: " + args[0]);
18164            return;
18165        }
18166
18167        pw.println("Applications Database Info:");
18168
18169        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18170            ProcessRecord r = procs.get(i);
18171            if (r.thread != null) {
18172                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
18173                pw.flush();
18174                try {
18175                    TransferPipe tp = new TransferPipe();
18176                    try {
18177                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
18178                        tp.go(fd);
18179                    } finally {
18180                        tp.kill();
18181                    }
18182                } catch (IOException e) {
18183                    pw.println("Failure while dumping the app: " + r);
18184                    pw.flush();
18185                } catch (RemoteException e) {
18186                    pw.println("Got a RemoteException while dumping the app " + r);
18187                    pw.flush();
18188                }
18189            }
18190        }
18191    }
18192
18193    final static class MemItem {
18194        final boolean isProc;
18195        final String label;
18196        final String shortLabel;
18197        final long pss;
18198        final long swapPss;
18199        final int id;
18200        final boolean hasActivities;
18201        ArrayList<MemItem> subitems;
18202
18203        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
18204                boolean _hasActivities) {
18205            isProc = true;
18206            label = _label;
18207            shortLabel = _shortLabel;
18208            pss = _pss;
18209            swapPss = _swapPss;
18210            id = _id;
18211            hasActivities = _hasActivities;
18212        }
18213
18214        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
18215            isProc = false;
18216            label = _label;
18217            shortLabel = _shortLabel;
18218            pss = _pss;
18219            swapPss = _swapPss;
18220            id = _id;
18221            hasActivities = false;
18222        }
18223    }
18224
18225    private static void sortMemItems(List<MemItem> items) {
18226        Collections.sort(items, new Comparator<MemItem>() {
18227            @Override
18228            public int compare(MemItem lhs, MemItem rhs) {
18229                if (lhs.pss < rhs.pss) {
18230                    return 1;
18231                } else if (lhs.pss > rhs.pss) {
18232                    return -1;
18233                }
18234                return 0;
18235            }
18236        });
18237    }
18238
18239    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
18240            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
18241        if (sort && !isCompact) {
18242            sortMemItems(items);
18243        }
18244
18245        for (int i=0; i<items.size(); i++) {
18246            MemItem mi = items.get(i);
18247            if (!isCompact) {
18248                if (dumpSwapPss) {
18249                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
18250                            mi.label, stringifyKBSize(mi.swapPss));
18251                } else {
18252                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
18253                }
18254            } else if (mi.isProc) {
18255                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
18256                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
18257                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
18258                pw.println(mi.hasActivities ? ",a" : ",e");
18259            } else {
18260                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
18261                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
18262            }
18263            if (mi.subitems != null) {
18264                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
18265                        true, isCompact, dumpSwapPss);
18266            }
18267        }
18268    }
18269
18270    static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
18271            ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
18272        if (sort) {
18273            sortMemItems(items);
18274        }
18275
18276        for (int i=0; i<items.size(); i++) {
18277            MemItem mi = items.get(i);
18278            final long token = proto.start(fieldId);
18279
18280            proto.write(MemInfoDumpProto.MemItem.TAG, tag);
18281            proto.write(MemInfoDumpProto.MemItem.LABEL, mi.shortLabel);
18282            proto.write(MemInfoDumpProto.MemItem.IS_PROC, mi.isProc);
18283            proto.write(MemInfoDumpProto.MemItem.ID, mi.id);
18284            proto.write(MemInfoDumpProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
18285            proto.write(MemInfoDumpProto.MemItem.PSS_KB, mi.pss);
18286            if (dumpSwapPss) {
18287                proto.write(MemInfoDumpProto.MemItem.SWAP_PSS_KB, mi.swapPss);
18288            }
18289            if (mi.subitems != null) {
18290                dumpMemItems(proto, MemInfoDumpProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
18291                        true, dumpSwapPss);
18292            }
18293            proto.end(token);
18294        }
18295    }
18296
18297    // These are in KB.
18298    static final long[] DUMP_MEM_BUCKETS = new long[] {
18299        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
18300        120*1024, 160*1024, 200*1024,
18301        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
18302        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
18303    };
18304
18305    static final void appendMemBucket(StringBuilder out, long memKB, String label,
18306            boolean stackLike) {
18307        int start = label.lastIndexOf('.');
18308        if (start >= 0) start++;
18309        else start = 0;
18310        int end = label.length();
18311        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
18312            if (DUMP_MEM_BUCKETS[i] >= memKB) {
18313                long bucket = DUMP_MEM_BUCKETS[i]/1024;
18314                out.append(bucket);
18315                out.append(stackLike ? "MB." : "MB ");
18316                out.append(label, start, end);
18317                return;
18318            }
18319        }
18320        out.append(memKB/1024);
18321        out.append(stackLike ? "MB." : "MB ");
18322        out.append(label, start, end);
18323    }
18324
18325    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
18326            ProcessList.NATIVE_ADJ,
18327            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
18328            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
18329            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
18330            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
18331            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
18332            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
18333    };
18334    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
18335            "Native",
18336            "System", "Persistent", "Persistent Service", "Foreground",
18337            "Visible", "Perceptible",
18338            "Heavy Weight", "Backup",
18339            "A Services", "Home",
18340            "Previous", "B Services", "Cached"
18341    };
18342    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
18343            "native",
18344            "sys", "pers", "persvc", "fore",
18345            "vis", "percept",
18346            "heavy", "backup",
18347            "servicea", "home",
18348            "prev", "serviceb", "cached"
18349    };
18350
18351    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
18352            long realtime, boolean isCheckinRequest, boolean isCompact) {
18353        if (isCompact) {
18354            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
18355        }
18356        if (isCheckinRequest || isCompact) {
18357            // short checkin version
18358            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
18359        } else {
18360            pw.println("Applications Memory Usage (in Kilobytes):");
18361            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18362        }
18363    }
18364
18365    private static final int KSM_SHARED = 0;
18366    private static final int KSM_SHARING = 1;
18367    private static final int KSM_UNSHARED = 2;
18368    private static final int KSM_VOLATILE = 3;
18369
18370    private final long[] getKsmInfo() {
18371        long[] longOut = new long[4];
18372        final int[] SINGLE_LONG_FORMAT = new int[] {
18373            PROC_SPACE_TERM| PROC_OUT_LONG
18374        };
18375        long[] longTmp = new long[1];
18376        readProcFile("/sys/kernel/mm/ksm/pages_shared",
18377                SINGLE_LONG_FORMAT, null, longTmp, null);
18378        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18379        longTmp[0] = 0;
18380        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
18381                SINGLE_LONG_FORMAT, null, longTmp, null);
18382        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18383        longTmp[0] = 0;
18384        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
18385                SINGLE_LONG_FORMAT, null, longTmp, null);
18386        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18387        longTmp[0] = 0;
18388        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
18389                SINGLE_LONG_FORMAT, null, longTmp, null);
18390        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18391        return longOut;
18392    }
18393
18394    private static String stringifySize(long size, int order) {
18395        Locale locale = Locale.US;
18396        switch (order) {
18397            case 1:
18398                return String.format(locale, "%,13d", size);
18399            case 1024:
18400                return String.format(locale, "%,9dK", size / 1024);
18401            case 1024 * 1024:
18402                return String.format(locale, "%,5dM", size / 1024 / 1024);
18403            case 1024 * 1024 * 1024:
18404                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
18405            default:
18406                throw new IllegalArgumentException("Invalid size order");
18407        }
18408    }
18409
18410    private static String stringifyKBSize(long size) {
18411        return stringifySize(size * 1024, 1024);
18412    }
18413
18414    // Update this version number if you change the 'compact' format.
18415    private static final int MEMINFO_COMPACT_VERSION = 1;
18416
18417    private static class MemoryUsageDumpOptions {
18418        boolean dumpDetails;
18419        boolean dumpFullDetails;
18420        boolean dumpDalvik;
18421        boolean dumpSummaryOnly;
18422        boolean dumpUnreachable;
18423        boolean oomOnly;
18424        boolean isCompact;
18425        boolean localOnly;
18426        boolean packages;
18427        boolean isCheckinRequest;
18428        boolean dumpSwapPss;
18429        boolean dumpProto;
18430    }
18431
18432    final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18433            String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) {
18434        MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions();
18435        opts.dumpDetails = false;
18436        opts.dumpFullDetails = false;
18437        opts.dumpDalvik = false;
18438        opts.dumpSummaryOnly = false;
18439        opts.dumpUnreachable = false;
18440        opts.oomOnly = false;
18441        opts.isCompact = false;
18442        opts.localOnly = false;
18443        opts.packages = false;
18444        opts.isCheckinRequest = false;
18445        opts.dumpSwapPss = false;
18446        opts.dumpProto = asProto;
18447
18448        int opti = 0;
18449        while (opti < args.length) {
18450            String opt = args[opti];
18451            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18452                break;
18453            }
18454            opti++;
18455            if ("-a".equals(opt)) {
18456                opts.dumpDetails = true;
18457                opts.dumpFullDetails = true;
18458                opts.dumpDalvik = true;
18459                opts.dumpSwapPss = true;
18460            } else if ("-d".equals(opt)) {
18461                opts.dumpDalvik = true;
18462            } else if ("-c".equals(opt)) {
18463                opts.isCompact = true;
18464            } else if ("-s".equals(opt)) {
18465                opts.dumpDetails = true;
18466                opts.dumpSummaryOnly = true;
18467            } else if ("-S".equals(opt)) {
18468                opts.dumpSwapPss = true;
18469            } else if ("--unreachable".equals(opt)) {
18470                opts.dumpUnreachable = true;
18471            } else if ("--oom".equals(opt)) {
18472                opts.oomOnly = true;
18473            } else if ("--local".equals(opt)) {
18474                opts.localOnly = true;
18475            } else if ("--package".equals(opt)) {
18476                opts.packages = true;
18477            } else if ("--checkin".equals(opt)) {
18478                opts.isCheckinRequest = true;
18479            } else if ("--proto".equals(opt)) {
18480                opts.dumpProto = true;
18481
18482            } else if ("-h".equals(opt)) {
18483                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
18484                pw.println("  -a: include all available information for each process.");
18485                pw.println("  -d: include dalvik details.");
18486                pw.println("  -c: dump in a compact machine-parseable representation.");
18487                pw.println("  -s: dump only summary of application memory usage.");
18488                pw.println("  -S: dump also SwapPss.");
18489                pw.println("  --oom: only show processes organized by oom adj.");
18490                pw.println("  --local: only collect details locally, don't call process.");
18491                pw.println("  --package: interpret process arg as package, dumping all");
18492                pw.println("             processes that have loaded that package.");
18493                pw.println("  --checkin: dump data for a checkin");
18494                pw.println("  --proto: dump data to proto");
18495                pw.println("If [process] is specified it can be the name or ");
18496                pw.println("pid of a specific process to dump.");
18497                return;
18498            } else {
18499                pw.println("Unknown argument: " + opt + "; use -h for help");
18500            }
18501        }
18502
18503        String[] innerArgs = new String[args.length-opti];
18504        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
18505
18506        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
18507        if (opts.dumpProto) {
18508            dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
18509        } else {
18510            dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
18511        }
18512    }
18513
18514    private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18515            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18516            ArrayList<ProcessRecord> procs, PrintWriter categoryPw) {
18517        long uptime = SystemClock.uptimeMillis();
18518        long realtime = SystemClock.elapsedRealtime();
18519        final long[] tmpLong = new long[1];
18520
18521        if (procs == null) {
18522            // No Java processes.  Maybe they want to print a native process.
18523            String proc = "N/A";
18524            if (innerArgs.length > 0) {
18525                proc = innerArgs[0];
18526                if (proc.charAt(0) != '-') {
18527                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
18528                            = new ArrayList<ProcessCpuTracker.Stats>();
18529                    updateCpuStatsNow();
18530                    int findPid = -1;
18531                    try {
18532                        findPid = Integer.parseInt(innerArgs[0]);
18533                    } catch (NumberFormatException e) {
18534                    }
18535                    synchronized (mProcessCpuTracker) {
18536                        final int N = mProcessCpuTracker.countStats();
18537                        for (int i=0; i<N; i++) {
18538                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18539                            if (st.pid == findPid || (st.baseName != null
18540                                    && st.baseName.equals(innerArgs[0]))) {
18541                                nativeProcs.add(st);
18542                            }
18543                        }
18544                    }
18545                    if (nativeProcs.size() > 0) {
18546                        dumpApplicationMemoryUsageHeader(pw, uptime, realtime,
18547                                opts.isCheckinRequest, opts.isCompact);
18548                        Debug.MemoryInfo mi = null;
18549                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18550                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18551                            final int pid = r.pid;
18552                            if (!opts.isCheckinRequest && opts.dumpDetails) {
18553                                pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
18554                            }
18555                            if (mi == null) {
18556                                mi = new Debug.MemoryInfo();
18557                            }
18558                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18559                                Debug.getMemoryInfo(pid, mi);
18560                            } else {
18561                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18562                                mi.dalvikPrivateDirty = (int)tmpLong[0];
18563                            }
18564                            ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest,
18565                                    opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18566                                    pid, r.baseName, 0, 0, 0, 0, 0, 0);
18567                            if (opts.isCheckinRequest) {
18568                                pw.println();
18569                            }
18570                        }
18571                        return;
18572                    }
18573                }
18574            }
18575            pw.println("No process found for: " + proc);
18576            return;
18577        }
18578
18579        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18580            opts.dumpDetails = true;
18581        }
18582
18583        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
18584
18585        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18586        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18587        long nativePss = 0;
18588        long nativeSwapPss = 0;
18589        long dalvikPss = 0;
18590        long dalvikSwapPss = 0;
18591        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18592                EmptyArray.LONG;
18593        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18594                EmptyArray.LONG;
18595        long otherPss = 0;
18596        long otherSwapPss = 0;
18597        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18598        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18599
18600        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18601        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18602        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18603                new ArrayList[DUMP_MEM_OOM_LABEL.length];
18604
18605        long totalPss = 0;
18606        long totalSwapPss = 0;
18607        long cachedPss = 0;
18608        long cachedSwapPss = 0;
18609        boolean hasSwapPss = false;
18610
18611        Debug.MemoryInfo mi = null;
18612        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18613            final ProcessRecord r = procs.get(i);
18614            final IApplicationThread thread;
18615            final int pid;
18616            final int oomAdj;
18617            final boolean hasActivities;
18618            synchronized (this) {
18619                thread = r.thread;
18620                pid = r.pid;
18621                oomAdj = r.getSetAdjWithServices();
18622                hasActivities = r.activities.size() > 0;
18623            }
18624            if (thread != null) {
18625                if (!opts.isCheckinRequest && opts.dumpDetails) {
18626                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
18627                }
18628                if (mi == null) {
18629                    mi = new Debug.MemoryInfo();
18630                }
18631                final int reportType;
18632                final long startTime;
18633                final long endTime;
18634                if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18635                    reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
18636                    startTime = SystemClock.currentThreadTimeMillis();
18637                    Debug.getMemoryInfo(pid, mi);
18638                    endTime = SystemClock.currentThreadTimeMillis();
18639                    hasSwapPss = mi.hasSwappedOutPss;
18640                } else {
18641                    reportType = ProcessStats.ADD_PSS_EXTERNAL;
18642                    startTime = SystemClock.currentThreadTimeMillis();
18643                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18644                    endTime = SystemClock.currentThreadTimeMillis();
18645                    mi.dalvikPrivateDirty = (int)tmpLong[0];
18646                }
18647                if (opts.dumpDetails) {
18648                    if (opts.localOnly) {
18649                        ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
18650                                opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
18651                        if (opts.isCheckinRequest) {
18652                            pw.println();
18653                        }
18654                    } else {
18655                        pw.flush();
18656                        try {
18657                            TransferPipe tp = new TransferPipe();
18658                            try {
18659                                thread.dumpMemInfo(tp.getWriteFd(),
18660                                        mi, opts.isCheckinRequest, opts.dumpFullDetails,
18661                                        opts.dumpDalvik, opts.dumpSummaryOnly, opts.dumpUnreachable, innerArgs);
18662                                tp.go(fd);
18663                            } finally {
18664                                tp.kill();
18665                            }
18666                        } catch (IOException e) {
18667                            if (!opts.isCheckinRequest) {
18668                                pw.println("Got IoException! " + e);
18669                                pw.flush();
18670                            }
18671                        } catch (RemoteException e) {
18672                            if (!opts.isCheckinRequest) {
18673                                pw.println("Got RemoteException! " + e);
18674                                pw.flush();
18675                            }
18676                        }
18677                    }
18678                }
18679
18680                final long myTotalPss = mi.getTotalPss();
18681                final long myTotalUss = mi.getTotalUss();
18682                final long myTotalRss = mi.getTotalRss();
18683                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18684
18685                synchronized (this) {
18686                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
18687                        // Record this for posterity if the process has been stable.
18688                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
18689                                reportType, endTime-startTime, r.pkgList);
18690                    }
18691                }
18692
18693                if (!opts.isCheckinRequest && mi != null) {
18694                    totalPss += myTotalPss;
18695                    totalSwapPss += myTotalSwapPss;
18696                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
18697                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
18698                            myTotalSwapPss, pid, hasActivities);
18699                    procMems.add(pssItem);
18700                    procMemsMap.put(pid, pssItem);
18701
18702                    nativePss += mi.nativePss;
18703                    nativeSwapPss += mi.nativeSwappedOutPss;
18704                    dalvikPss += mi.dalvikPss;
18705                    dalvikSwapPss += mi.dalvikSwappedOutPss;
18706                    for (int j=0; j<dalvikSubitemPss.length; j++) {
18707                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18708                        dalvikSubitemSwapPss[j] +=
18709                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18710                    }
18711                    otherPss += mi.otherPss;
18712                    otherSwapPss += mi.otherSwappedOutPss;
18713                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18714                        long mem = mi.getOtherPss(j);
18715                        miscPss[j] += mem;
18716                        otherPss -= mem;
18717                        mem = mi.getOtherSwappedOutPss(j);
18718                        miscSwapPss[j] += mem;
18719                        otherSwapPss -= mem;
18720                    }
18721
18722                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
18723                        cachedPss += myTotalPss;
18724                        cachedSwapPss += myTotalSwapPss;
18725                    }
18726
18727                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
18728                        if (oomIndex == (oomPss.length - 1)
18729                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
18730                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
18731                            oomPss[oomIndex] += myTotalPss;
18732                            oomSwapPss[oomIndex] += myTotalSwapPss;
18733                            if (oomProcs[oomIndex] == null) {
18734                                oomProcs[oomIndex] = new ArrayList<MemItem>();
18735                            }
18736                            oomProcs[oomIndex].add(pssItem);
18737                            break;
18738                        }
18739                    }
18740                }
18741            }
18742        }
18743
18744        long nativeProcTotalPss = 0;
18745
18746        if (!opts.isCheckinRequest && procs.size() > 1 && !opts.packages) {
18747            // If we are showing aggregations, also look for native processes to
18748            // include so that our aggregations are more accurate.
18749            updateCpuStatsNow();
18750            mi = null;
18751            synchronized (mProcessCpuTracker) {
18752                final int N = mProcessCpuTracker.countStats();
18753                for (int i=0; i<N; i++) {
18754                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18755                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
18756                        if (mi == null) {
18757                            mi = new Debug.MemoryInfo();
18758                        }
18759                        if (!brief && !opts.oomOnly) {
18760                            Debug.getMemoryInfo(st.pid, mi);
18761                        } else {
18762                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
18763                            mi.nativePrivateDirty = (int)tmpLong[0];
18764                        }
18765
18766                        final long myTotalPss = mi.getTotalPss();
18767                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18768                        totalPss += myTotalPss;
18769                        totalSwapPss += myTotalSwapPss;
18770                        nativeProcTotalPss += myTotalPss;
18771
18772                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
18773                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
18774                        procMems.add(pssItem);
18775
18776                        nativePss += mi.nativePss;
18777                        nativeSwapPss += mi.nativeSwappedOutPss;
18778                        dalvikPss += mi.dalvikPss;
18779                        dalvikSwapPss += mi.dalvikSwappedOutPss;
18780                        for (int j=0; j<dalvikSubitemPss.length; j++) {
18781                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18782                            dalvikSubitemSwapPss[j] +=
18783                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18784                        }
18785                        otherPss += mi.otherPss;
18786                        otherSwapPss += mi.otherSwappedOutPss;
18787                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18788                            long mem = mi.getOtherPss(j);
18789                            miscPss[j] += mem;
18790                            otherPss -= mem;
18791                            mem = mi.getOtherSwappedOutPss(j);
18792                            miscSwapPss[j] += mem;
18793                            otherSwapPss -= mem;
18794                        }
18795                        oomPss[0] += myTotalPss;
18796                        oomSwapPss[0] += myTotalSwapPss;
18797                        if (oomProcs[0] == null) {
18798                            oomProcs[0] = new ArrayList<MemItem>();
18799                        }
18800                        oomProcs[0].add(pssItem);
18801                    }
18802                }
18803            }
18804
18805            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
18806
18807            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
18808            final int dalvikId = -2;
18809            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
18810            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
18811            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18812                String label = Debug.MemoryInfo.getOtherLabel(j);
18813                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
18814            }
18815            if (dalvikSubitemPss.length > 0) {
18816                // Add dalvik subitems.
18817                for (MemItem memItem : catMems) {
18818                    int memItemStart = 0, memItemEnd = 0;
18819                    if (memItem.id == dalvikId) {
18820                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
18821                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
18822                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
18823                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
18824                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
18825                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
18826                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
18827                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
18828                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
18829                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
18830                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
18831                    } else {
18832                        continue;  // No subitems, continue.
18833                    }
18834                    memItem.subitems = new ArrayList<MemItem>();
18835                    for (int j=memItemStart; j<=memItemEnd; j++) {
18836                        final String name = Debug.MemoryInfo.getOtherLabel(
18837                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
18838                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
18839                                dalvikSubitemSwapPss[j], j));
18840                    }
18841                }
18842            }
18843
18844            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
18845            for (int j=0; j<oomPss.length; j++) {
18846                if (oomPss[j] != 0) {
18847                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
18848                            : DUMP_MEM_OOM_LABEL[j];
18849                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
18850                            DUMP_MEM_OOM_ADJ[j]);
18851                    item.subitems = oomProcs[j];
18852                    oomMems.add(item);
18853                }
18854            }
18855
18856            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
18857            if (!brief && !opts.oomOnly && !opts.isCompact) {
18858                pw.println();
18859                pw.println("Total PSS by process:");
18860                dumpMemItems(pw, "  ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
18861                pw.println();
18862            }
18863            if (!opts.isCompact) {
18864                pw.println("Total PSS by OOM adjustment:");
18865            }
18866            dumpMemItems(pw, "  ", "oom", oomMems, false, opts.isCompact, opts.dumpSwapPss);
18867            if (!brief && !opts.oomOnly) {
18868                PrintWriter out = categoryPw != null ? categoryPw : pw;
18869                if (!opts.isCompact) {
18870                    out.println();
18871                    out.println("Total PSS by category:");
18872                }
18873                dumpMemItems(out, "  ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
18874            }
18875            if (!opts.isCompact) {
18876                pw.println();
18877            }
18878            MemInfoReader memInfo = new MemInfoReader();
18879            memInfo.readMemInfo();
18880            if (nativeProcTotalPss > 0) {
18881                synchronized (this) {
18882                    final long cachedKb = memInfo.getCachedSizeKb();
18883                    final long freeKb = memInfo.getFreeSizeKb();
18884                    final long zramKb = memInfo.getZramTotalSizeKb();
18885                    final long kernelKb = memInfo.getKernelUsedSizeKb();
18886                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
18887                            kernelKb*1024, nativeProcTotalPss*1024);
18888                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
18889                            nativeProcTotalPss);
18890                }
18891            }
18892            if (!brief) {
18893                if (!opts.isCompact) {
18894                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
18895                    pw.print(" (status ");
18896                    switch (mLastMemoryLevel) {
18897                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
18898                            pw.println("normal)");
18899                            break;
18900                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
18901                            pw.println("moderate)");
18902                            break;
18903                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
18904                            pw.println("low)");
18905                            break;
18906                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18907                            pw.println("critical)");
18908                            break;
18909                        default:
18910                            pw.print(mLastMemoryLevel);
18911                            pw.println(")");
18912                            break;
18913                    }
18914                    pw.print(" Free RAM: ");
18915                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
18916                            + memInfo.getFreeSizeKb()));
18917                    pw.print(" (");
18918                    pw.print(stringifyKBSize(cachedPss));
18919                    pw.print(" cached pss + ");
18920                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
18921                    pw.print(" cached kernel + ");
18922                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
18923                    pw.println(" free)");
18924                } else {
18925                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
18926                    pw.print(cachedPss + memInfo.getCachedSizeKb()
18927                            + memInfo.getFreeSizeKb()); pw.print(",");
18928                    pw.println(totalPss - cachedPss);
18929                }
18930            }
18931            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
18932                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
18933                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
18934            if (!opts.isCompact) {
18935                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
18936                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
18937                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
18938                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
18939                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
18940            } else {
18941                pw.print("lostram,"); pw.println(lostRAM);
18942            }
18943            if (!brief) {
18944                if (memInfo.getZramTotalSizeKb() != 0) {
18945                    if (!opts.isCompact) {
18946                        pw.print("     ZRAM: ");
18947                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
18948                                pw.print(" physical used for ");
18949                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
18950                                        - memInfo.getSwapFreeSizeKb()));
18951                                pw.print(" in swap (");
18952                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
18953                                pw.println(" total swap)");
18954                    } else {
18955                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
18956                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
18957                                pw.println(memInfo.getSwapFreeSizeKb());
18958                    }
18959                }
18960                final long[] ksm = getKsmInfo();
18961                if (!opts.isCompact) {
18962                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
18963                            || ksm[KSM_VOLATILE] != 0) {
18964                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
18965                                pw.print(" saved from shared ");
18966                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
18967                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
18968                                pw.print(" unshared; ");
18969                                pw.print(stringifyKBSize(
18970                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
18971                    }
18972                    pw.print("   Tuning: ");
18973                    pw.print(ActivityManager.staticGetMemoryClass());
18974                    pw.print(" (large ");
18975                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18976                    pw.print("), oom ");
18977                    pw.print(stringifySize(
18978                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
18979                    pw.print(", restore limit ");
18980                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
18981                    if (ActivityManager.isLowRamDeviceStatic()) {
18982                        pw.print(" (low-ram)");
18983                    }
18984                    if (ActivityManager.isHighEndGfx()) {
18985                        pw.print(" (high-end-gfx)");
18986                    }
18987                    pw.println();
18988                } else {
18989                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
18990                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
18991                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
18992                    pw.print("tuning,");
18993                    pw.print(ActivityManager.staticGetMemoryClass());
18994                    pw.print(',');
18995                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18996                    pw.print(',');
18997                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
18998                    if (ActivityManager.isLowRamDeviceStatic()) {
18999                        pw.print(",low-ram");
19000                    }
19001                    if (ActivityManager.isHighEndGfx()) {
19002                        pw.print(",high-end-gfx");
19003                    }
19004                    pw.println();
19005                }
19006            }
19007        }
19008    }
19009
19010    private final void dumpApplicationMemoryUsage(FileDescriptor fd,
19011            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
19012            ArrayList<ProcessRecord> procs) {
19013        final long uptimeMs = SystemClock.uptimeMillis();
19014        final long realtimeMs = SystemClock.elapsedRealtime();
19015        final long[] tmpLong = new long[1];
19016
19017        if (procs == null) {
19018            // No Java processes.  Maybe they want to print a native process.
19019            String proc = "N/A";
19020            if (innerArgs.length > 0) {
19021                proc = innerArgs[0];
19022                if (proc.charAt(0) != '-') {
19023                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
19024                            = new ArrayList<ProcessCpuTracker.Stats>();
19025                    updateCpuStatsNow();
19026                    int findPid = -1;
19027                    try {
19028                        findPid = Integer.parseInt(innerArgs[0]);
19029                    } catch (NumberFormatException e) {
19030                    }
19031                    synchronized (mProcessCpuTracker) {
19032                        final int N = mProcessCpuTracker.countStats();
19033                        for (int i=0; i<N; i++) {
19034                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19035                            if (st.pid == findPid || (st.baseName != null
19036                                    && st.baseName.equals(innerArgs[0]))) {
19037                                nativeProcs.add(st);
19038                            }
19039                        }
19040                    }
19041                    if (nativeProcs.size() > 0) {
19042                        ProtoOutputStream proto = new ProtoOutputStream(fd);
19043
19044                        proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
19045                        proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
19046                        Debug.MemoryInfo mi = null;
19047                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
19048                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
19049                            final int pid = r.pid;
19050                            final long nToken = proto.start(MemInfoDumpProto.NATIVE_PROCESSES);
19051
19052                            proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
19053                            proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName);
19054
19055                            if (mi == null) {
19056                                mi = new Debug.MemoryInfo();
19057                            }
19058                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19059                                Debug.getMemoryInfo(pid, mi);
19060                            } else {
19061                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
19062                                mi.dalvikPrivateDirty = (int)tmpLong[0];
19063                            }
19064                            ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19065                                    opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19066
19067                            proto.end(nToken);
19068                        }
19069
19070                        proto.flush();
19071                        return;
19072                    }
19073                }
19074            }
19075            Log.d(TAG, "No process found for: " + innerArgs[0]);
19076            return;
19077        }
19078
19079        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
19080            opts.dumpDetails = true;
19081        }
19082
19083        ProtoOutputStream proto = new ProtoOutputStream(fd);
19084
19085        proto.write(MemInfoDumpProto.UPTIME_DURATION_MS, uptimeMs);
19086        proto.write(MemInfoDumpProto.ELAPSED_REALTIME_MS, realtimeMs);
19087
19088        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
19089        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
19090        long nativePss = 0;
19091        long nativeSwapPss = 0;
19092        long dalvikPss = 0;
19093        long dalvikSwapPss = 0;
19094        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19095                EmptyArray.LONG;
19096        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19097                EmptyArray.LONG;
19098        long otherPss = 0;
19099        long otherSwapPss = 0;
19100        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19101        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19102
19103        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19104        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19105        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
19106                new ArrayList[DUMP_MEM_OOM_LABEL.length];
19107
19108        long totalPss = 0;
19109        long totalSwapPss = 0;
19110        long cachedPss = 0;
19111        long cachedSwapPss = 0;
19112        boolean hasSwapPss = false;
19113
19114        Debug.MemoryInfo mi = null;
19115        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
19116            final ProcessRecord r = procs.get(i);
19117            final IApplicationThread thread;
19118            final int pid;
19119            final int oomAdj;
19120            final boolean hasActivities;
19121            synchronized (this) {
19122                thread = r.thread;
19123                pid = r.pid;
19124                oomAdj = r.getSetAdjWithServices();
19125                hasActivities = r.activities.size() > 0;
19126            }
19127            if (thread == null) {
19128                continue;
19129            }
19130            if (mi == null) {
19131                mi = new Debug.MemoryInfo();
19132            }
19133            final int reportType;
19134            final long startTime;
19135            final long endTime;
19136            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19137                reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
19138                startTime = SystemClock.currentThreadTimeMillis();
19139                Debug.getMemoryInfo(pid, mi);
19140                endTime = SystemClock.currentThreadTimeMillis();
19141                hasSwapPss = mi.hasSwappedOutPss;
19142            } else {
19143                reportType = ProcessStats.ADD_PSS_EXTERNAL;
19144                startTime = SystemClock.currentThreadTimeMillis();
19145                mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
19146                endTime = SystemClock.currentThreadTimeMillis();
19147                mi.dalvikPrivateDirty = (int) tmpLong[0];
19148            }
19149            if (opts.dumpDetails) {
19150                if (opts.localOnly) {
19151                    final long aToken = proto.start(MemInfoDumpProto.APP_PROCESSES);
19152                    final long mToken = proto.start(MemInfoDumpProto.AppData.PROCESS_MEMORY);
19153                    proto.write(MemInfoDumpProto.ProcessMemory.PID, pid);
19154                    proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.processName);
19155                    ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19156                            opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19157                    proto.end(mToken);
19158                    proto.end(aToken);
19159                } else {
19160                    try {
19161                        ByteTransferPipe tp = new ByteTransferPipe();
19162                        try {
19163                            thread.dumpMemInfoProto(tp.getWriteFd(),
19164                                mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
19165                                opts.dumpUnreachable, innerArgs);
19166                            proto.write(MemInfoDumpProto.APP_PROCESSES, tp.get());
19167                        } finally {
19168                            tp.kill();
19169                        }
19170                    } catch (IOException e) {
19171                        Log.e(TAG, "Got IOException!", e);
19172                    } catch (RemoteException e) {
19173                        Log.e(TAG, "Got RemoteException!", e);
19174                    }
19175                }
19176            }
19177
19178            final long myTotalPss = mi.getTotalPss();
19179            final long myTotalUss = mi.getTotalUss();
19180            final long myTotalRss = mi.getTotalRss();
19181            final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19182
19183            synchronized (this) {
19184                if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
19185                    // Record this for posterity if the process has been stable.
19186                    r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
19187                            reportType, endTime-startTime, r.pkgList);
19188                }
19189            }
19190
19191            if (!opts.isCheckinRequest && mi != null) {
19192                totalPss += myTotalPss;
19193                totalSwapPss += myTotalSwapPss;
19194                MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
19195                        (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
19196                        myTotalSwapPss, pid, hasActivities);
19197                procMems.add(pssItem);
19198                procMemsMap.put(pid, pssItem);
19199
19200                nativePss += mi.nativePss;
19201                nativeSwapPss += mi.nativeSwappedOutPss;
19202                dalvikPss += mi.dalvikPss;
19203                dalvikSwapPss += mi.dalvikSwappedOutPss;
19204                for (int j=0; j<dalvikSubitemPss.length; j++) {
19205                    dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19206                    dalvikSubitemSwapPss[j] +=
19207                            mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19208                }
19209                otherPss += mi.otherPss;
19210                otherSwapPss += mi.otherSwappedOutPss;
19211                for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19212                    long mem = mi.getOtherPss(j);
19213                    miscPss[j] += mem;
19214                    otherPss -= mem;
19215                    mem = mi.getOtherSwappedOutPss(j);
19216                    miscSwapPss[j] += mem;
19217                    otherSwapPss -= mem;
19218                }
19219
19220                if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19221                    cachedPss += myTotalPss;
19222                    cachedSwapPss += myTotalSwapPss;
19223                }
19224
19225                for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
19226                    if (oomIndex == (oomPss.length - 1)
19227                            || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
19228                                    && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
19229                        oomPss[oomIndex] += myTotalPss;
19230                        oomSwapPss[oomIndex] += myTotalSwapPss;
19231                        if (oomProcs[oomIndex] == null) {
19232                            oomProcs[oomIndex] = new ArrayList<MemItem>();
19233                        }
19234                        oomProcs[oomIndex].add(pssItem);
19235                        break;
19236                    }
19237                }
19238            }
19239        }
19240
19241        long nativeProcTotalPss = 0;
19242
19243        if (procs.size() > 1 && !opts.packages) {
19244            // If we are showing aggregations, also look for native processes to
19245            // include so that our aggregations are more accurate.
19246            updateCpuStatsNow();
19247            mi = null;
19248            synchronized (mProcessCpuTracker) {
19249                final int N = mProcessCpuTracker.countStats();
19250                for (int i=0; i<N; i++) {
19251                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19252                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
19253                        if (mi == null) {
19254                            mi = new Debug.MemoryInfo();
19255                        }
19256                        if (!brief && !opts.oomOnly) {
19257                            Debug.getMemoryInfo(st.pid, mi);
19258                        } else {
19259                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19260                            mi.nativePrivateDirty = (int)tmpLong[0];
19261                        }
19262
19263                        final long myTotalPss = mi.getTotalPss();
19264                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19265                        totalPss += myTotalPss;
19266                        nativeProcTotalPss += myTotalPss;
19267
19268                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19269                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19270                        procMems.add(pssItem);
19271
19272                        nativePss += mi.nativePss;
19273                        nativeSwapPss += mi.nativeSwappedOutPss;
19274                        dalvikPss += mi.dalvikPss;
19275                        dalvikSwapPss += mi.dalvikSwappedOutPss;
19276                        for (int j=0; j<dalvikSubitemPss.length; j++) {
19277                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19278                            dalvikSubitemSwapPss[j] +=
19279                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19280                        }
19281                        otherPss += mi.otherPss;
19282                        otherSwapPss += mi.otherSwappedOutPss;
19283                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19284                            long mem = mi.getOtherPss(j);
19285                            miscPss[j] += mem;
19286                            otherPss -= mem;
19287                            mem = mi.getOtherSwappedOutPss(j);
19288                            miscSwapPss[j] += mem;
19289                            otherSwapPss -= mem;
19290                        }
19291                        oomPss[0] += myTotalPss;
19292                        oomSwapPss[0] += myTotalSwapPss;
19293                        if (oomProcs[0] == null) {
19294                            oomProcs[0] = new ArrayList<MemItem>();
19295                        }
19296                        oomProcs[0].add(pssItem);
19297                    }
19298                }
19299            }
19300
19301            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19302
19303            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19304            final int dalvikId = -2;
19305            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19306            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19307            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19308                String label = Debug.MemoryInfo.getOtherLabel(j);
19309                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19310            }
19311            if (dalvikSubitemPss.length > 0) {
19312                // Add dalvik subitems.
19313                for (MemItem memItem : catMems) {
19314                    int memItemStart = 0, memItemEnd = 0;
19315                    if (memItem.id == dalvikId) {
19316                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19317                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19318                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19319                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19320                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19321                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19322                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19323                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19324                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19325                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19326                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19327                    } else {
19328                        continue;  // No subitems, continue.
19329                    }
19330                    memItem.subitems = new ArrayList<MemItem>();
19331                    for (int j=memItemStart; j<=memItemEnd; j++) {
19332                        final String name = Debug.MemoryInfo.getOtherLabel(
19333                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
19334                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19335                                dalvikSubitemSwapPss[j], j));
19336                    }
19337                }
19338            }
19339
19340            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19341            for (int j=0; j<oomPss.length; j++) {
19342                if (oomPss[j] != 0) {
19343                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19344                            : DUMP_MEM_OOM_LABEL[j];
19345                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19346                            DUMP_MEM_OOM_ADJ[j]);
19347                    item.subitems = oomProcs[j];
19348                    oomMems.add(item);
19349                }
19350            }
19351
19352            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19353            if (!opts.oomOnly) {
19354                dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_PROCESS, "proc",
19355                        procMems, true, opts.dumpSwapPss);
19356            }
19357            dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
19358                    oomMems, false, opts.dumpSwapPss);
19359            if (!brief && !opts.oomOnly) {
19360                dumpMemItems(proto, MemInfoDumpProto.TOTAL_PSS_BY_CATEGORY, "cat",
19361                        catMems, true, opts.dumpSwapPss);
19362            }
19363            MemInfoReader memInfo = new MemInfoReader();
19364            memInfo.readMemInfo();
19365            if (nativeProcTotalPss > 0) {
19366                synchronized (this) {
19367                    final long cachedKb = memInfo.getCachedSizeKb();
19368                    final long freeKb = memInfo.getFreeSizeKb();
19369                    final long zramKb = memInfo.getZramTotalSizeKb();
19370                    final long kernelKb = memInfo.getKernelUsedSizeKb();
19371                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19372                            kernelKb*1024, nativeProcTotalPss*1024);
19373                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19374                            nativeProcTotalPss);
19375                }
19376            }
19377            if (!brief) {
19378                proto.write(MemInfoDumpProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
19379                proto.write(MemInfoDumpProto.STATUS, mLastMemoryLevel);
19380                proto.write(MemInfoDumpProto.CACHED_PSS_KB, cachedPss);
19381                proto.write(MemInfoDumpProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
19382                proto.write(MemInfoDumpProto.FREE_KB, memInfo.getFreeSizeKb());
19383            }
19384            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19385                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19386                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19387            proto.write(MemInfoDumpProto.USED_PSS_KB, totalPss - cachedPss);
19388            proto.write(MemInfoDumpProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
19389            proto.write(MemInfoDumpProto.LOST_RAM_KB, lostRAM);
19390            if (!brief) {
19391                if (memInfo.getZramTotalSizeKb() != 0) {
19392                    proto.write(MemInfoDumpProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
19393                    proto.write(MemInfoDumpProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
19394                            memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
19395                    proto.write(MemInfoDumpProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
19396                }
19397                final long[] ksm = getKsmInfo();
19398                proto.write(MemInfoDumpProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
19399                proto.write(MemInfoDumpProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
19400                proto.write(MemInfoDumpProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
19401                proto.write(MemInfoDumpProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
19402
19403                proto.write(MemInfoDumpProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
19404                proto.write(MemInfoDumpProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
19405                proto.write(MemInfoDumpProto.OOM_KB,
19406                        mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
19407                proto.write(MemInfoDumpProto.RESTORE_LIMIT_KB,
19408                        mProcessList.getCachedRestoreThresholdKb());
19409
19410                proto.write(MemInfoDumpProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
19411                proto.write(MemInfoDumpProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
19412            }
19413        }
19414
19415        proto.flush();
19416    }
19417
19418    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
19419            long memtrack, String name) {
19420        sb.append("  ");
19421        sb.append(ProcessList.makeOomAdjString(oomAdj));
19422        sb.append(' ');
19423        sb.append(ProcessList.makeProcStateString(procState));
19424        sb.append(' ');
19425        ProcessList.appendRamKb(sb, pss);
19426        sb.append(": ");
19427        sb.append(name);
19428        if (memtrack > 0) {
19429            sb.append(" (");
19430            sb.append(stringifyKBSize(memtrack));
19431            sb.append(" memtrack)");
19432        }
19433    }
19434
19435    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
19436        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
19437        sb.append(" (pid ");
19438        sb.append(mi.pid);
19439        sb.append(") ");
19440        sb.append(mi.adjType);
19441        sb.append('\n');
19442        if (mi.adjReason != null) {
19443            sb.append("                      ");
19444            sb.append(mi.adjReason);
19445            sb.append('\n');
19446        }
19447    }
19448
19449    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
19450        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
19451        for (int i=0, N=memInfos.size(); i<N; i++) {
19452            ProcessMemInfo mi = memInfos.get(i);
19453            infoMap.put(mi.pid, mi);
19454        }
19455        updateCpuStatsNow();
19456        long[] memtrackTmp = new long[1];
19457        final List<ProcessCpuTracker.Stats> stats;
19458        // Get a list of Stats that have vsize > 0
19459        synchronized (mProcessCpuTracker) {
19460            stats = mProcessCpuTracker.getStats((st) -> {
19461                return st.vsize > 0;
19462            });
19463        }
19464        final int statsCount = stats.size();
19465        for (int i = 0; i < statsCount; i++) {
19466            ProcessCpuTracker.Stats st = stats.get(i);
19467            long pss = Debug.getPss(st.pid, null, memtrackTmp);
19468            if (pss > 0) {
19469                if (infoMap.indexOfKey(st.pid) < 0) {
19470                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
19471                            ProcessList.NATIVE_ADJ, -1, "native", null);
19472                    mi.pss = pss;
19473                    mi.memtrack = memtrackTmp[0];
19474                    memInfos.add(mi);
19475                }
19476            }
19477        }
19478
19479        long totalPss = 0;
19480        long totalMemtrack = 0;
19481        for (int i=0, N=memInfos.size(); i<N; i++) {
19482            ProcessMemInfo mi = memInfos.get(i);
19483            if (mi.pss == 0) {
19484                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
19485                mi.memtrack = memtrackTmp[0];
19486            }
19487            totalPss += mi.pss;
19488            totalMemtrack += mi.memtrack;
19489        }
19490        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
19491            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
19492                if (lhs.oomAdj != rhs.oomAdj) {
19493                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
19494                }
19495                if (lhs.pss != rhs.pss) {
19496                    return lhs.pss < rhs.pss ? 1 : -1;
19497                }
19498                return 0;
19499            }
19500        });
19501
19502        StringBuilder tag = new StringBuilder(128);
19503        StringBuilder stack = new StringBuilder(128);
19504        tag.append("Low on memory -- ");
19505        appendMemBucket(tag, totalPss, "total", false);
19506        appendMemBucket(stack, totalPss, "total", true);
19507
19508        StringBuilder fullNativeBuilder = new StringBuilder(1024);
19509        StringBuilder shortNativeBuilder = new StringBuilder(1024);
19510        StringBuilder fullJavaBuilder = new StringBuilder(1024);
19511
19512        boolean firstLine = true;
19513        int lastOomAdj = Integer.MIN_VALUE;
19514        long extraNativeRam = 0;
19515        long extraNativeMemtrack = 0;
19516        long cachedPss = 0;
19517        for (int i=0, N=memInfos.size(); i<N; i++) {
19518            ProcessMemInfo mi = memInfos.get(i);
19519
19520            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19521                cachedPss += mi.pss;
19522            }
19523
19524            if (mi.oomAdj != ProcessList.NATIVE_ADJ
19525                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
19526                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
19527                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
19528                if (lastOomAdj != mi.oomAdj) {
19529                    lastOomAdj = mi.oomAdj;
19530                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19531                        tag.append(" / ");
19532                    }
19533                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
19534                        if (firstLine) {
19535                            stack.append(":");
19536                            firstLine = false;
19537                        }
19538                        stack.append("\n\t at ");
19539                    } else {
19540                        stack.append("$");
19541                    }
19542                } else {
19543                    tag.append(" ");
19544                    stack.append("$");
19545                }
19546                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19547                    appendMemBucket(tag, mi.pss, mi.name, false);
19548                }
19549                appendMemBucket(stack, mi.pss, mi.name, true);
19550                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
19551                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
19552                    stack.append("(");
19553                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
19554                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
19555                            stack.append(DUMP_MEM_OOM_LABEL[k]);
19556                            stack.append(":");
19557                            stack.append(DUMP_MEM_OOM_ADJ[k]);
19558                        }
19559                    }
19560                    stack.append(")");
19561                }
19562            }
19563
19564            appendMemInfo(fullNativeBuilder, mi);
19565            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
19566                // The short form only has native processes that are >= 512K.
19567                if (mi.pss >= 512) {
19568                    appendMemInfo(shortNativeBuilder, mi);
19569                } else {
19570                    extraNativeRam += mi.pss;
19571                    extraNativeMemtrack += mi.memtrack;
19572                }
19573            } else {
19574                // Short form has all other details, but if we have collected RAM
19575                // from smaller native processes let's dump a summary of that.
19576                if (extraNativeRam > 0) {
19577                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
19578                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
19579                    shortNativeBuilder.append('\n');
19580                    extraNativeRam = 0;
19581                }
19582                appendMemInfo(fullJavaBuilder, mi);
19583            }
19584        }
19585
19586        fullJavaBuilder.append("           ");
19587        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
19588        fullJavaBuilder.append(": TOTAL");
19589        if (totalMemtrack > 0) {
19590            fullJavaBuilder.append(" (");
19591            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
19592            fullJavaBuilder.append(" memtrack)");
19593        } else {
19594        }
19595        fullJavaBuilder.append("\n");
19596
19597        MemInfoReader memInfo = new MemInfoReader();
19598        memInfo.readMemInfo();
19599        final long[] infos = memInfo.getRawInfo();
19600
19601        StringBuilder memInfoBuilder = new StringBuilder(1024);
19602        Debug.getMemInfo(infos);
19603        memInfoBuilder.append("  MemInfo: ");
19604        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
19605        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
19606        memInfoBuilder.append(stringifyKBSize(
19607                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
19608        memInfoBuilder.append(stringifyKBSize(
19609                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
19610        memInfoBuilder.append(stringifyKBSize(
19611                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
19612        memInfoBuilder.append("           ");
19613        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
19614        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
19615        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
19616        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
19617        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
19618            memInfoBuilder.append("  ZRAM: ");
19619            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
19620            memInfoBuilder.append(" RAM, ");
19621            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
19622            memInfoBuilder.append(" swap total, ");
19623            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
19624            memInfoBuilder.append(" swap free\n");
19625        }
19626        final long[] ksm = getKsmInfo();
19627        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
19628                || ksm[KSM_VOLATILE] != 0) {
19629            memInfoBuilder.append("  KSM: ");
19630            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
19631            memInfoBuilder.append(" saved from shared ");
19632            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
19633            memInfoBuilder.append("\n       ");
19634            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
19635            memInfoBuilder.append(" unshared; ");
19636            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
19637            memInfoBuilder.append(" volatile\n");
19638        }
19639        memInfoBuilder.append("  Free RAM: ");
19640        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19641                + memInfo.getFreeSizeKb()));
19642        memInfoBuilder.append("\n");
19643        memInfoBuilder.append("  Used RAM: ");
19644        memInfoBuilder.append(stringifyKBSize(
19645                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
19646        memInfoBuilder.append("\n");
19647        memInfoBuilder.append("  Lost RAM: ");
19648        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
19649                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19650                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
19651        memInfoBuilder.append("\n");
19652        Slog.i(TAG, "Low on memory:");
19653        Slog.i(TAG, shortNativeBuilder.toString());
19654        Slog.i(TAG, fullJavaBuilder.toString());
19655        Slog.i(TAG, memInfoBuilder.toString());
19656
19657        StringBuilder dropBuilder = new StringBuilder(1024);
19658        /*
19659        StringWriter oomSw = new StringWriter();
19660        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
19661        StringWriter catSw = new StringWriter();
19662        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19663        String[] emptyArgs = new String[] { };
19664        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
19665        oomPw.flush();
19666        String oomString = oomSw.toString();
19667        */
19668        dropBuilder.append("Low on memory:");
19669        dropBuilder.append(stack);
19670        dropBuilder.append('\n');
19671        dropBuilder.append(fullNativeBuilder);
19672        dropBuilder.append(fullJavaBuilder);
19673        dropBuilder.append('\n');
19674        dropBuilder.append(memInfoBuilder);
19675        dropBuilder.append('\n');
19676        /*
19677        dropBuilder.append(oomString);
19678        dropBuilder.append('\n');
19679        */
19680        StringWriter catSw = new StringWriter();
19681        synchronized (ActivityManagerService.this) {
19682            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19683            String[] emptyArgs = new String[] { };
19684            catPw.println();
19685            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
19686            catPw.println();
19687            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
19688                    false, null).dumpLocked();
19689            catPw.println();
19690            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
19691            catPw.flush();
19692        }
19693        dropBuilder.append(catSw.toString());
19694        addErrorToDropBox("lowmem", null, "system_server", null,
19695                null, tag.toString(), dropBuilder.toString(), null, null);
19696        //Slog.i(TAG, "Sent to dropbox:");
19697        //Slog.i(TAG, dropBuilder.toString());
19698        synchronized (ActivityManagerService.this) {
19699            long now = SystemClock.uptimeMillis();
19700            if (mLastMemUsageReportTime < now) {
19701                mLastMemUsageReportTime = now;
19702            }
19703        }
19704    }
19705
19706    /**
19707     * Searches array of arguments for the specified string
19708     * @param args array of argument strings
19709     * @param value value to search for
19710     * @return true if the value is contained in the array
19711     */
19712    private static boolean scanArgs(String[] args, String value) {
19713        if (args != null) {
19714            for (String arg : args) {
19715                if (value.equals(arg)) {
19716                    return true;
19717                }
19718            }
19719        }
19720        return false;
19721    }
19722
19723    private final boolean removeDyingProviderLocked(ProcessRecord proc,
19724            ContentProviderRecord cpr, boolean always) {
19725        final boolean inLaunching = mLaunchingProviders.contains(cpr);
19726
19727        if (!inLaunching || always) {
19728            synchronized (cpr) {
19729                cpr.launchingApp = null;
19730                cpr.notifyAll();
19731            }
19732            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
19733            String names[] = cpr.info.authority.split(";");
19734            for (int j = 0; j < names.length; j++) {
19735                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
19736            }
19737        }
19738
19739        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
19740            ContentProviderConnection conn = cpr.connections.get(i);
19741            if (conn.waiting) {
19742                // If this connection is waiting for the provider, then we don't
19743                // need to mess with its process unless we are always removing
19744                // or for some reason the provider is not currently launching.
19745                if (inLaunching && !always) {
19746                    continue;
19747                }
19748            }
19749            ProcessRecord capp = conn.client;
19750            conn.dead = true;
19751            if (conn.stableCount > 0) {
19752                if (!capp.persistent && capp.thread != null
19753                        && capp.pid != 0
19754                        && capp.pid != MY_PID) {
19755                    capp.kill("depends on provider "
19756                            + cpr.name.flattenToShortString()
19757                            + " in dying proc " + (proc != null ? proc.processName : "??")
19758                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
19759                }
19760            } else if (capp.thread != null && conn.provider.provider != null) {
19761                try {
19762                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
19763                } catch (RemoteException e) {
19764                }
19765                // In the protocol here, we don't expect the client to correctly
19766                // clean up this connection, we'll just remove it.
19767                cpr.connections.remove(i);
19768                if (conn.client.conProviders.remove(conn)) {
19769                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
19770                }
19771            }
19772        }
19773
19774        if (inLaunching && always) {
19775            mLaunchingProviders.remove(cpr);
19776        }
19777        return inLaunching;
19778    }
19779
19780    /**
19781     * Main code for cleaning up a process when it has gone away.  This is
19782     * called both as a result of the process dying, or directly when stopping
19783     * a process when running in single process mode.
19784     *
19785     * @return Returns true if the given process has been restarted, so the
19786     * app that was passed in must remain on the process lists.
19787     */
19788    @GuardedBy("this")
19789    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
19790            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
19791        if (index >= 0) {
19792            removeLruProcessLocked(app);
19793            ProcessList.remove(app.pid);
19794        }
19795
19796        mProcessesToGc.remove(app);
19797        mPendingPssProcesses.remove(app);
19798        ProcessList.abortNextPssTime(app.procStateMemTracker);
19799
19800        // Dismiss any open dialogs.
19801        if (app.crashDialog != null && !app.forceCrashReport) {
19802            app.crashDialog.dismiss();
19803            app.crashDialog = null;
19804        }
19805        if (app.anrDialog != null) {
19806            app.anrDialog.dismiss();
19807            app.anrDialog = null;
19808        }
19809        if (app.waitDialog != null) {
19810            app.waitDialog.dismiss();
19811            app.waitDialog = null;
19812        }
19813
19814        app.crashing = false;
19815        app.notResponding = false;
19816
19817        app.resetPackageList(mProcessStats);
19818        app.unlinkDeathRecipient();
19819        app.makeInactive(mProcessStats);
19820        app.waitingToKill = null;
19821        app.forcingToImportant = null;
19822        updateProcessForegroundLocked(app, false, false);
19823        app.foregroundActivities = false;
19824        app.hasShownUi = false;
19825        app.treatLikeActivity = false;
19826        app.hasAboveClient = false;
19827        app.hasClientActivities = false;
19828
19829        mServices.killServicesLocked(app, allowRestart);
19830
19831        boolean restart = false;
19832
19833        // Remove published content providers.
19834        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
19835            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
19836            final boolean always = app.bad || !allowRestart;
19837            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
19838            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
19839                // We left the provider in the launching list, need to
19840                // restart it.
19841                restart = true;
19842            }
19843
19844            cpr.provider = null;
19845            cpr.proc = null;
19846        }
19847        app.pubProviders.clear();
19848
19849        // Take care of any launching providers waiting for this process.
19850        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
19851            restart = true;
19852        }
19853
19854        // Unregister from connected content providers.
19855        if (!app.conProviders.isEmpty()) {
19856            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
19857                ContentProviderConnection conn = app.conProviders.get(i);
19858                conn.provider.connections.remove(conn);
19859                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
19860                        conn.provider.name);
19861            }
19862            app.conProviders.clear();
19863        }
19864
19865        // At this point there may be remaining entries in mLaunchingProviders
19866        // where we were the only one waiting, so they are no longer of use.
19867        // Look for these and clean up if found.
19868        // XXX Commented out for now.  Trying to figure out a way to reproduce
19869        // the actual situation to identify what is actually going on.
19870        if (false) {
19871            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19872                ContentProviderRecord cpr = mLaunchingProviders.get(i);
19873                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
19874                    synchronized (cpr) {
19875                        cpr.launchingApp = null;
19876                        cpr.notifyAll();
19877                    }
19878                }
19879            }
19880        }
19881
19882        skipCurrentReceiverLocked(app);
19883
19884        // Unregister any receivers.
19885        for (int i = app.receivers.size() - 1; i >= 0; i--) {
19886            removeReceiverLocked(app.receivers.valueAt(i));
19887        }
19888        app.receivers.clear();
19889
19890        // If the app is undergoing backup, tell the backup manager about it
19891        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
19892            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
19893                    + mBackupTarget.appInfo + " died during backup");
19894            mHandler.post(new Runnable() {
19895                @Override
19896                public void run(){
19897                    try {
19898                        IBackupManager bm = IBackupManager.Stub.asInterface(
19899                                ServiceManager.getService(Context.BACKUP_SERVICE));
19900                        bm.agentDisconnected(app.info.packageName);
19901                    } catch (RemoteException e) {
19902                        // can't happen; backup manager is local
19903                    }
19904                }
19905            });
19906        }
19907
19908        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
19909            ProcessChangeItem item = mPendingProcessChanges.get(i);
19910            if (app.pid > 0 && item.pid == app.pid) {
19911                mPendingProcessChanges.remove(i);
19912                mAvailProcessChanges.add(item);
19913            }
19914        }
19915        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
19916                null).sendToTarget();
19917
19918        // If the caller is restarting this app, then leave it in its
19919        // current lists and let the caller take care of it.
19920        if (restarting) {
19921            return false;
19922        }
19923
19924        if (!app.persistent || app.isolated) {
19925            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
19926                    "Removing non-persistent process during cleanup: " + app);
19927            if (!replacingPid) {
19928                removeProcessNameLocked(app.processName, app.uid, app);
19929            }
19930            if (mHeavyWeightProcess == app) {
19931                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
19932                        mHeavyWeightProcess.userId, 0));
19933                mHeavyWeightProcess = null;
19934            }
19935        } else if (!app.removed) {
19936            // This app is persistent, so we need to keep its record around.
19937            // If it is not already on the pending app list, add it there
19938            // and start a new process for it.
19939            if (mPersistentStartingProcesses.indexOf(app) < 0) {
19940                mPersistentStartingProcesses.add(app);
19941                restart = true;
19942            }
19943        }
19944        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
19945                TAG_CLEANUP, "Clean-up removing on hold: " + app);
19946        mProcessesOnHold.remove(app);
19947
19948        if (app == mHomeProcess) {
19949            mHomeProcess = null;
19950        }
19951        if (app == mPreviousProcess) {
19952            mPreviousProcess = null;
19953        }
19954
19955        if (restart && !app.isolated) {
19956            // We have components that still need to be running in the
19957            // process, so re-launch it.
19958            if (index < 0) {
19959                ProcessList.remove(app.pid);
19960            }
19961            addProcessNameLocked(app);
19962            app.pendingStart = false;
19963            startProcessLocked(app, "restart", app.processName);
19964            return true;
19965        } else if (app.pid > 0 && app.pid != MY_PID) {
19966            // Goodbye!
19967            boolean removed;
19968            synchronized (mPidsSelfLocked) {
19969                mPidsSelfLocked.remove(app.pid);
19970                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
19971            }
19972            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
19973            if (app.isolated) {
19974                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
19975            }
19976            app.setPid(0);
19977        }
19978        return false;
19979    }
19980
19981    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
19982        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19983            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19984            if (cpr.launchingApp == app) {
19985                return true;
19986            }
19987        }
19988        return false;
19989    }
19990
19991    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
19992        // Look through the content providers we are waiting to have launched,
19993        // and if any run in this process then either schedule a restart of
19994        // the process or kill the client waiting for it if this process has
19995        // gone bad.
19996        boolean restart = false;
19997        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19998            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19999            if (cpr.launchingApp == app) {
20000                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
20001                    restart = true;
20002                } else {
20003                    removeDyingProviderLocked(app, cpr, true);
20004                }
20005            }
20006        }
20007        return restart;
20008    }
20009
20010    // =========================================================
20011    // SERVICES
20012    // =========================================================
20013
20014    @Override
20015    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
20016        enforceNotIsolatedCaller("getServices");
20017
20018        final int callingUid = Binder.getCallingUid();
20019        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
20020            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
20021        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
20022            callingUid);
20023        synchronized (this) {
20024            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
20025                allowed, canInteractAcrossUsers);
20026        }
20027    }
20028
20029    @Override
20030    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
20031        enforceNotIsolatedCaller("getRunningServiceControlPanel");
20032        synchronized (this) {
20033            return mServices.getRunningServiceControlPanelLocked(name);
20034        }
20035    }
20036
20037    @Override
20038    public ComponentName startService(IApplicationThread caller, Intent service,
20039            String resolvedType, boolean requireForeground, String callingPackage, int userId)
20040            throws TransactionTooLargeException {
20041        enforceNotIsolatedCaller("startService");
20042        // Refuse possible leaked file descriptors
20043        if (service != null && service.hasFileDescriptors() == true) {
20044            throw new IllegalArgumentException("File descriptors passed in Intent");
20045        }
20046
20047        if (callingPackage == null) {
20048            throw new IllegalArgumentException("callingPackage cannot be null");
20049        }
20050
20051        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20052                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
20053        synchronized(this) {
20054            final int callingPid = Binder.getCallingPid();
20055            final int callingUid = Binder.getCallingUid();
20056            final long origId = Binder.clearCallingIdentity();
20057            ComponentName res;
20058            try {
20059                res = mServices.startServiceLocked(caller, service,
20060                        resolvedType, callingPid, callingUid,
20061                        requireForeground, callingPackage, userId);
20062            } finally {
20063                Binder.restoreCallingIdentity(origId);
20064            }
20065            return res;
20066        }
20067    }
20068
20069    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
20070            boolean fgRequired, String callingPackage, int userId)
20071            throws TransactionTooLargeException {
20072        synchronized(this) {
20073            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20074                    "startServiceInPackage: " + service + " type=" + resolvedType);
20075            final long origId = Binder.clearCallingIdentity();
20076            ComponentName res;
20077            try {
20078                res = mServices.startServiceLocked(null, service,
20079                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
20080            } finally {
20081                Binder.restoreCallingIdentity(origId);
20082            }
20083            return res;
20084        }
20085    }
20086
20087    @Override
20088    public int stopService(IApplicationThread caller, Intent service,
20089            String resolvedType, int userId) {
20090        enforceNotIsolatedCaller("stopService");
20091        // Refuse possible leaked file descriptors
20092        if (service != null && service.hasFileDescriptors() == true) {
20093            throw new IllegalArgumentException("File descriptors passed in Intent");
20094        }
20095
20096        synchronized(this) {
20097            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
20098        }
20099    }
20100
20101    @Override
20102    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
20103        enforceNotIsolatedCaller("peekService");
20104        // Refuse possible leaked file descriptors
20105        if (service != null && service.hasFileDescriptors() == true) {
20106            throw new IllegalArgumentException("File descriptors passed in Intent");
20107        }
20108
20109        if (callingPackage == null) {
20110            throw new IllegalArgumentException("callingPackage cannot be null");
20111        }
20112
20113        synchronized(this) {
20114            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
20115        }
20116    }
20117
20118    @Override
20119    public boolean stopServiceToken(ComponentName className, IBinder token,
20120            int startId) {
20121        synchronized(this) {
20122            return mServices.stopServiceTokenLocked(className, token, startId);
20123        }
20124    }
20125
20126    @Override
20127    public void setServiceForeground(ComponentName className, IBinder token,
20128            int id, Notification notification, int flags) {
20129        synchronized(this) {
20130            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
20131        }
20132    }
20133
20134    @Override
20135    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
20136            boolean requireFull, String name, String callerPackage) {
20137        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
20138                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
20139    }
20140
20141    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
20142            String className, int flags) {
20143        boolean result = false;
20144        // For apps that don't have pre-defined UIDs, check for permission
20145        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
20146            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20147                if (ActivityManager.checkUidPermission(
20148                        INTERACT_ACROSS_USERS,
20149                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
20150                    ComponentName comp = new ComponentName(aInfo.packageName, className);
20151                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
20152                            + " requests FLAG_SINGLE_USER, but app does not hold "
20153                            + INTERACT_ACROSS_USERS;
20154                    Slog.w(TAG, msg);
20155                    throw new SecurityException(msg);
20156                }
20157                // Permission passed
20158                result = true;
20159            }
20160        } else if ("system".equals(componentProcessName)) {
20161            result = true;
20162        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20163            // Phone app and persistent apps are allowed to export singleuser providers.
20164            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
20165                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
20166        }
20167        if (DEBUG_MU) Slog.v(TAG_MU,
20168                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
20169                + Integer.toHexString(flags) + ") = " + result);
20170        return result;
20171    }
20172
20173    /**
20174     * Checks to see if the caller is in the same app as the singleton
20175     * component, or the component is in a special app. It allows special apps
20176     * to export singleton components but prevents exporting singleton
20177     * components for regular apps.
20178     */
20179    boolean isValidSingletonCall(int callingUid, int componentUid) {
20180        int componentAppId = UserHandle.getAppId(componentUid);
20181        return UserHandle.isSameApp(callingUid, componentUid)
20182                || componentAppId == SYSTEM_UID
20183                || componentAppId == PHONE_UID
20184                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
20185                        == PackageManager.PERMISSION_GRANTED;
20186    }
20187
20188    public int bindService(IApplicationThread caller, IBinder token, Intent service,
20189            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
20190            int userId) throws TransactionTooLargeException {
20191        enforceNotIsolatedCaller("bindService");
20192
20193        // Refuse possible leaked file descriptors
20194        if (service != null && service.hasFileDescriptors() == true) {
20195            throw new IllegalArgumentException("File descriptors passed in Intent");
20196        }
20197
20198        if (callingPackage == null) {
20199            throw new IllegalArgumentException("callingPackage cannot be null");
20200        }
20201
20202        synchronized(this) {
20203            return mServices.bindServiceLocked(caller, token, service,
20204                    resolvedType, connection, flags, callingPackage, userId);
20205        }
20206    }
20207
20208    public boolean unbindService(IServiceConnection connection) {
20209        synchronized (this) {
20210            return mServices.unbindServiceLocked(connection);
20211        }
20212    }
20213
20214    public void publishService(IBinder token, Intent intent, IBinder service) {
20215        // Refuse possible leaked file descriptors
20216        if (intent != null && intent.hasFileDescriptors() == true) {
20217            throw new IllegalArgumentException("File descriptors passed in Intent");
20218        }
20219
20220        synchronized(this) {
20221            if (!(token instanceof ServiceRecord)) {
20222                throw new IllegalArgumentException("Invalid service token");
20223            }
20224            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
20225        }
20226    }
20227
20228    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
20229        // Refuse possible leaked file descriptors
20230        if (intent != null && intent.hasFileDescriptors() == true) {
20231            throw new IllegalArgumentException("File descriptors passed in Intent");
20232        }
20233
20234        synchronized(this) {
20235            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
20236        }
20237    }
20238
20239    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
20240        synchronized(this) {
20241            if (!(token instanceof ServiceRecord)) {
20242                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
20243                throw new IllegalArgumentException("Invalid service token");
20244            }
20245            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
20246        }
20247    }
20248
20249    // =========================================================
20250    // BACKUP AND RESTORE
20251    // =========================================================
20252
20253    // Cause the target app to be launched if necessary and its backup agent
20254    // instantiated.  The backup agent will invoke backupAgentCreated() on the
20255    // activity manager to announce its creation.
20256    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
20257        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
20258        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
20259
20260        IPackageManager pm = AppGlobals.getPackageManager();
20261        ApplicationInfo app = null;
20262        try {
20263            app = pm.getApplicationInfo(packageName, 0, userId);
20264        } catch (RemoteException e) {
20265            // can't happen; package manager is process-local
20266        }
20267        if (app == null) {
20268            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
20269            return false;
20270        }
20271
20272        int oldBackupUid;
20273        int newBackupUid;
20274
20275        synchronized(this) {
20276            // !!! TODO: currently no check here that we're already bound
20277            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
20278            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20279            synchronized (stats) {
20280                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
20281            }
20282
20283            // Backup agent is now in use, its package can't be stopped.
20284            try {
20285                AppGlobals.getPackageManager().setPackageStoppedState(
20286                        app.packageName, false, UserHandle.getUserId(app.uid));
20287            } catch (RemoteException e) {
20288            } catch (IllegalArgumentException e) {
20289                Slog.w(TAG, "Failed trying to unstop package "
20290                        + app.packageName + ": " + e);
20291            }
20292
20293            BackupRecord r = new BackupRecord(ss, app, backupMode);
20294            ComponentName hostingName =
20295                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
20296                            ? new ComponentName(app.packageName, app.backupAgentName)
20297                            : new ComponentName("android", "FullBackupAgent");
20298            // startProcessLocked() returns existing proc's record if it's already running
20299            ProcessRecord proc = startProcessLocked(app.processName, app,
20300                    false, 0, "backup", hostingName, false, false, false);
20301            if (proc == null) {
20302                Slog.e(TAG, "Unable to start backup agent process " + r);
20303                return false;
20304            }
20305
20306            // If the app is a regular app (uid >= 10000) and not the system server or phone
20307            // process, etc, then mark it as being in full backup so that certain calls to the
20308            // process can be blocked. This is not reset to false anywhere because we kill the
20309            // process after the full backup is done and the ProcessRecord will vaporize anyway.
20310            if (UserHandle.isApp(app.uid) &&
20311                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
20312                proc.inFullBackup = true;
20313            }
20314            r.app = proc;
20315            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20316            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
20317            mBackupTarget = r;
20318            mBackupAppName = app.packageName;
20319
20320            // Try not to kill the process during backup
20321            updateOomAdjLocked(proc, true);
20322
20323            // If the process is already attached, schedule the creation of the backup agent now.
20324            // If it is not yet live, this will be done when it attaches to the framework.
20325            if (proc.thread != null) {
20326                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
20327                try {
20328                    proc.thread.scheduleCreateBackupAgent(app,
20329                            compatibilityInfoForPackageLocked(app), backupMode);
20330                } catch (RemoteException e) {
20331                    // Will time out on the backup manager side
20332                }
20333            } else {
20334                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
20335            }
20336            // Invariants: at this point, the target app process exists and the application
20337            // is either already running or in the process of coming up.  mBackupTarget and
20338            // mBackupAppName describe the app, so that when it binds back to the AM we
20339            // know that it's scheduled for a backup-agent operation.
20340        }
20341
20342        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20343        if (oldBackupUid != -1) {
20344            js.removeBackingUpUid(oldBackupUid);
20345        }
20346        if (newBackupUid != -1) {
20347            js.addBackingUpUid(newBackupUid);
20348        }
20349
20350        return true;
20351    }
20352
20353    @Override
20354    public void clearPendingBackup() {
20355        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
20356        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
20357
20358        synchronized (this) {
20359            mBackupTarget = null;
20360            mBackupAppName = null;
20361        }
20362
20363        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20364        js.clearAllBackingUpUids();
20365    }
20366
20367    // A backup agent has just come up
20368    public void backupAgentCreated(String agentPackageName, IBinder agent) {
20369        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
20370                + " = " + agent);
20371
20372        synchronized(this) {
20373            if (!agentPackageName.equals(mBackupAppName)) {
20374                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
20375                return;
20376            }
20377        }
20378
20379        long oldIdent = Binder.clearCallingIdentity();
20380        try {
20381            IBackupManager bm = IBackupManager.Stub.asInterface(
20382                    ServiceManager.getService(Context.BACKUP_SERVICE));
20383            bm.agentConnected(agentPackageName, agent);
20384        } catch (RemoteException e) {
20385            // can't happen; the backup manager service is local
20386        } catch (Exception e) {
20387            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
20388            e.printStackTrace();
20389        } finally {
20390            Binder.restoreCallingIdentity(oldIdent);
20391        }
20392    }
20393
20394    // done with this agent
20395    public void unbindBackupAgent(ApplicationInfo appInfo) {
20396        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
20397        if (appInfo == null) {
20398            Slog.w(TAG, "unbind backup agent for null app");
20399            return;
20400        }
20401
20402        int oldBackupUid;
20403
20404        synchronized(this) {
20405            try {
20406                if (mBackupAppName == null) {
20407                    Slog.w(TAG, "Unbinding backup agent with no active backup");
20408                    return;
20409                }
20410
20411                if (!mBackupAppName.equals(appInfo.packageName)) {
20412                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
20413                    return;
20414                }
20415
20416                // Not backing this app up any more; reset its OOM adjustment
20417                final ProcessRecord proc = mBackupTarget.app;
20418                updateOomAdjLocked(proc, true);
20419                proc.inFullBackup = false;
20420
20421                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20422
20423                // If the app crashed during backup, 'thread' will be null here
20424                if (proc.thread != null) {
20425                    try {
20426                        proc.thread.scheduleDestroyBackupAgent(appInfo,
20427                                compatibilityInfoForPackageLocked(appInfo));
20428                    } catch (Exception e) {
20429                        Slog.e(TAG, "Exception when unbinding backup agent:");
20430                        e.printStackTrace();
20431                    }
20432                }
20433            } finally {
20434                mBackupTarget = null;
20435                mBackupAppName = null;
20436            }
20437        }
20438
20439        if (oldBackupUid != -1) {
20440            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20441            js.removeBackingUpUid(oldBackupUid);
20442        }
20443    }
20444
20445    // =========================================================
20446    // BROADCASTS
20447    // =========================================================
20448
20449    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
20450        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
20451            return false;
20452        }
20453        // Easy case -- we have the app's ProcessRecord.
20454        if (record != null) {
20455            return record.info.isInstantApp();
20456        }
20457        // Otherwise check with PackageManager.
20458        if (callerPackage == null) {
20459            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
20460            throw new IllegalArgumentException("Calling application did not provide package name");
20461        }
20462        mAppOpsService.checkPackage(uid, callerPackage);
20463        try {
20464            IPackageManager pm = AppGlobals.getPackageManager();
20465            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
20466        } catch (RemoteException e) {
20467            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
20468            return true;
20469        }
20470    }
20471
20472    boolean isPendingBroadcastProcessLocked(int pid) {
20473        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
20474                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
20475    }
20476
20477    void skipPendingBroadcastLocked(int pid) {
20478            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
20479            for (BroadcastQueue queue : mBroadcastQueues) {
20480                queue.skipPendingBroadcastLocked(pid);
20481            }
20482    }
20483
20484    // The app just attached; send any pending broadcasts that it should receive
20485    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
20486        boolean didSomething = false;
20487        for (BroadcastQueue queue : mBroadcastQueues) {
20488            didSomething |= queue.sendPendingBroadcastsLocked(app);
20489        }
20490        return didSomething;
20491    }
20492
20493    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
20494            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
20495            int flags) {
20496        enforceNotIsolatedCaller("registerReceiver");
20497        ArrayList<Intent> stickyIntents = null;
20498        ProcessRecord callerApp = null;
20499        final boolean visibleToInstantApps
20500                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
20501        int callingUid;
20502        int callingPid;
20503        boolean instantApp;
20504        synchronized(this) {
20505            if (caller != null) {
20506                callerApp = getRecordForAppLocked(caller);
20507                if (callerApp == null) {
20508                    throw new SecurityException(
20509                            "Unable to find app for caller " + caller
20510                            + " (pid=" + Binder.getCallingPid()
20511                            + ") when registering receiver " + receiver);
20512                }
20513                if (callerApp.info.uid != SYSTEM_UID &&
20514                        !callerApp.pkgList.containsKey(callerPackage) &&
20515                        !"android".equals(callerPackage)) {
20516                    throw new SecurityException("Given caller package " + callerPackage
20517                            + " is not running in process " + callerApp);
20518                }
20519                callingUid = callerApp.info.uid;
20520                callingPid = callerApp.pid;
20521            } else {
20522                callerPackage = null;
20523                callingUid = Binder.getCallingUid();
20524                callingPid = Binder.getCallingPid();
20525            }
20526
20527            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
20528            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20529                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
20530
20531            Iterator<String> actions = filter.actionsIterator();
20532            if (actions == null) {
20533                ArrayList<String> noAction = new ArrayList<String>(1);
20534                noAction.add(null);
20535                actions = noAction.iterator();
20536            }
20537
20538            // Collect stickies of users
20539            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
20540            while (actions.hasNext()) {
20541                String action = actions.next();
20542                for (int id : userIds) {
20543                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
20544                    if (stickies != null) {
20545                        ArrayList<Intent> intents = stickies.get(action);
20546                        if (intents != null) {
20547                            if (stickyIntents == null) {
20548                                stickyIntents = new ArrayList<Intent>();
20549                            }
20550                            stickyIntents.addAll(intents);
20551                        }
20552                    }
20553                }
20554            }
20555        }
20556
20557        ArrayList<Intent> allSticky = null;
20558        if (stickyIntents != null) {
20559            final ContentResolver resolver = mContext.getContentResolver();
20560            // Look for any matching sticky broadcasts...
20561            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
20562                Intent intent = stickyIntents.get(i);
20563                // Don't provided intents that aren't available to instant apps.
20564                if (instantApp &&
20565                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
20566                    continue;
20567                }
20568                // If intent has scheme "content", it will need to acccess
20569                // provider that needs to lock mProviderMap in ActivityThread
20570                // and also it may need to wait application response, so we
20571                // cannot lock ActivityManagerService here.
20572                if (filter.match(resolver, intent, true, TAG) >= 0) {
20573                    if (allSticky == null) {
20574                        allSticky = new ArrayList<Intent>();
20575                    }
20576                    allSticky.add(intent);
20577                }
20578            }
20579        }
20580
20581        // The first sticky in the list is returned directly back to the client.
20582        Intent sticky = allSticky != null ? allSticky.get(0) : null;
20583        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
20584        if (receiver == null) {
20585            return sticky;
20586        }
20587
20588        synchronized (this) {
20589            if (callerApp != null && (callerApp.thread == null
20590                    || callerApp.thread.asBinder() != caller.asBinder())) {
20591                // Original caller already died
20592                return null;
20593            }
20594            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20595            if (rl == null) {
20596                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
20597                        userId, receiver);
20598                if (rl.app != null) {
20599                    final int totalReceiversForApp = rl.app.receivers.size();
20600                    if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
20601                        throw new IllegalStateException("Too many receivers, total of "
20602                                + totalReceiversForApp + ", registered for pid: "
20603                                + rl.pid + ", callerPackage: " + callerPackage);
20604                    }
20605                    rl.app.receivers.add(rl);
20606                } else {
20607                    try {
20608                        receiver.asBinder().linkToDeath(rl, 0);
20609                    } catch (RemoteException e) {
20610                        return sticky;
20611                    }
20612                    rl.linkedToDeath = true;
20613                }
20614                mRegisteredReceivers.put(receiver.asBinder(), rl);
20615            } else if (rl.uid != callingUid) {
20616                throw new IllegalArgumentException(
20617                        "Receiver requested to register for uid " + callingUid
20618                        + " was previously registered for uid " + rl.uid
20619                        + " callerPackage is " + callerPackage);
20620            } else if (rl.pid != callingPid) {
20621                throw new IllegalArgumentException(
20622                        "Receiver requested to register for pid " + callingPid
20623                        + " was previously registered for pid " + rl.pid
20624                        + " callerPackage is " + callerPackage);
20625            } else if (rl.userId != userId) {
20626                throw new IllegalArgumentException(
20627                        "Receiver requested to register for user " + userId
20628                        + " was previously registered for user " + rl.userId
20629                        + " callerPackage is " + callerPackage);
20630            }
20631            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
20632                    permission, callingUid, userId, instantApp, visibleToInstantApps);
20633            if (rl.containsFilter(filter)) {
20634                Slog.w(TAG, "Receiver with filter " + filter
20635                        + " already registered for pid " + rl.pid
20636                        + ", callerPackage is " + callerPackage);
20637            } else {
20638                rl.add(bf);
20639                if (!bf.debugCheck()) {
20640                    Slog.w(TAG, "==> For Dynamic broadcast");
20641                }
20642                mReceiverResolver.addFilter(bf);
20643            }
20644
20645            // Enqueue broadcasts for all existing stickies that match
20646            // this filter.
20647            if (allSticky != null) {
20648                ArrayList receivers = new ArrayList();
20649                receivers.add(bf);
20650
20651                final int stickyCount = allSticky.size();
20652                for (int i = 0; i < stickyCount; i++) {
20653                    Intent intent = allSticky.get(i);
20654                    BroadcastQueue queue = broadcastQueueForIntent(intent);
20655                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
20656                            null, -1, -1, false, null, null, OP_NONE, null, receivers,
20657                            null, 0, null, null, false, true, true, -1);
20658                    queue.enqueueParallelBroadcastLocked(r);
20659                    queue.scheduleBroadcastsLocked();
20660                }
20661            }
20662
20663            return sticky;
20664        }
20665    }
20666
20667    public void unregisterReceiver(IIntentReceiver receiver) {
20668        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
20669
20670        final long origId = Binder.clearCallingIdentity();
20671        try {
20672            boolean doTrim = false;
20673
20674            synchronized(this) {
20675                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20676                if (rl != null) {
20677                    final BroadcastRecord r = rl.curBroadcast;
20678                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
20679                        final boolean doNext = r.queue.finishReceiverLocked(
20680                                r, r.resultCode, r.resultData, r.resultExtras,
20681                                r.resultAbort, false);
20682                        if (doNext) {
20683                            doTrim = true;
20684                            r.queue.processNextBroadcast(false);
20685                        }
20686                    }
20687
20688                    if (rl.app != null) {
20689                        rl.app.receivers.remove(rl);
20690                    }
20691                    removeReceiverLocked(rl);
20692                    if (rl.linkedToDeath) {
20693                        rl.linkedToDeath = false;
20694                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
20695                    }
20696                }
20697            }
20698
20699            // If we actually concluded any broadcasts, we might now be able
20700            // to trim the recipients' apps from our working set
20701            if (doTrim) {
20702                trimApplications();
20703                return;
20704            }
20705
20706        } finally {
20707            Binder.restoreCallingIdentity(origId);
20708        }
20709    }
20710
20711    void removeReceiverLocked(ReceiverList rl) {
20712        mRegisteredReceivers.remove(rl.receiver.asBinder());
20713        for (int i = rl.size() - 1; i >= 0; i--) {
20714            mReceiverResolver.removeFilter(rl.get(i));
20715        }
20716    }
20717
20718    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
20719        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20720            ProcessRecord r = mLruProcesses.get(i);
20721            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
20722                try {
20723                    r.thread.dispatchPackageBroadcast(cmd, packages);
20724                } catch (RemoteException ex) {
20725                }
20726            }
20727        }
20728    }
20729
20730    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
20731            int callingUid, int[] users) {
20732        // TODO: come back and remove this assumption to triage all broadcasts
20733        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
20734
20735        List<ResolveInfo> receivers = null;
20736        try {
20737            HashSet<ComponentName> singleUserReceivers = null;
20738            boolean scannedFirstReceivers = false;
20739            for (int user : users) {
20740                // Skip users that have Shell restrictions, with exception of always permitted
20741                // Shell broadcasts
20742                if (callingUid == SHELL_UID
20743                        && mUserController.hasUserRestriction(
20744                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
20745                        && !isPermittedShellBroadcast(intent)) {
20746                    continue;
20747                }
20748                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
20749                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
20750                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
20751                    // If this is not the system user, we need to check for
20752                    // any receivers that should be filtered out.
20753                    for (int i=0; i<newReceivers.size(); i++) {
20754                        ResolveInfo ri = newReceivers.get(i);
20755                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
20756                            newReceivers.remove(i);
20757                            i--;
20758                        }
20759                    }
20760                }
20761                if (newReceivers != null && newReceivers.size() == 0) {
20762                    newReceivers = null;
20763                }
20764                if (receivers == null) {
20765                    receivers = newReceivers;
20766                } else if (newReceivers != null) {
20767                    // We need to concatenate the additional receivers
20768                    // found with what we have do far.  This would be easy,
20769                    // but we also need to de-dup any receivers that are
20770                    // singleUser.
20771                    if (!scannedFirstReceivers) {
20772                        // Collect any single user receivers we had already retrieved.
20773                        scannedFirstReceivers = true;
20774                        for (int i=0; i<receivers.size(); i++) {
20775                            ResolveInfo ri = receivers.get(i);
20776                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20777                                ComponentName cn = new ComponentName(
20778                                        ri.activityInfo.packageName, ri.activityInfo.name);
20779                                if (singleUserReceivers == null) {
20780                                    singleUserReceivers = new HashSet<ComponentName>();
20781                                }
20782                                singleUserReceivers.add(cn);
20783                            }
20784                        }
20785                    }
20786                    // Add the new results to the existing results, tracking
20787                    // and de-dupping single user receivers.
20788                    for (int i=0; i<newReceivers.size(); i++) {
20789                        ResolveInfo ri = newReceivers.get(i);
20790                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20791                            ComponentName cn = new ComponentName(
20792                                    ri.activityInfo.packageName, ri.activityInfo.name);
20793                            if (singleUserReceivers == null) {
20794                                singleUserReceivers = new HashSet<ComponentName>();
20795                            }
20796                            if (!singleUserReceivers.contains(cn)) {
20797                                singleUserReceivers.add(cn);
20798                                receivers.add(ri);
20799                            }
20800                        } else {
20801                            receivers.add(ri);
20802                        }
20803                    }
20804                }
20805            }
20806        } catch (RemoteException ex) {
20807            // pm is in same process, this will never happen.
20808        }
20809        return receivers;
20810    }
20811
20812    private boolean isPermittedShellBroadcast(Intent intent) {
20813        // remote bugreport should always be allowed to be taken
20814        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
20815    }
20816
20817    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
20818            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
20819        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
20820            // Don't yell about broadcasts sent via shell
20821            return;
20822        }
20823
20824        final String action = intent.getAction();
20825        if (isProtectedBroadcast
20826                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
20827                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
20828                || Intent.ACTION_MEDIA_BUTTON.equals(action)
20829                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
20830                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
20831                || Intent.ACTION_MASTER_CLEAR.equals(action)
20832                || Intent.ACTION_FACTORY_RESET.equals(action)
20833                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
20834                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
20835                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
20836                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
20837                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
20838                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
20839                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
20840            // Broadcast is either protected, or it's a public action that
20841            // we've relaxed, so it's fine for system internals to send.
20842            return;
20843        }
20844
20845        // This broadcast may be a problem...  but there are often system components that
20846        // want to send an internal broadcast to themselves, which is annoying to have to
20847        // explicitly list each action as a protected broadcast, so we will check for that
20848        // one safe case and allow it: an explicit broadcast, only being received by something
20849        // that has protected itself.
20850        if (receivers != null && receivers.size() > 0
20851                && (intent.getPackage() != null || intent.getComponent() != null)) {
20852            boolean allProtected = true;
20853            for (int i = receivers.size()-1; i >= 0; i--) {
20854                Object target = receivers.get(i);
20855                if (target instanceof ResolveInfo) {
20856                    ResolveInfo ri = (ResolveInfo)target;
20857                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
20858                        allProtected = false;
20859                        break;
20860                    }
20861                } else {
20862                    BroadcastFilter bf = (BroadcastFilter)target;
20863                    if (bf.requiredPermission == null) {
20864                        allProtected = false;
20865                        break;
20866                    }
20867                }
20868            }
20869            if (allProtected) {
20870                // All safe!
20871                return;
20872            }
20873        }
20874
20875        // The vast majority of broadcasts sent from system internals
20876        // should be protected to avoid security holes, so yell loudly
20877        // to ensure we examine these cases.
20878        if (callerApp != null) {
20879            Log.wtf(TAG, "Sending non-protected broadcast " + action
20880                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
20881                    new Throwable());
20882        } else {
20883            Log.wtf(TAG, "Sending non-protected broadcast " + action
20884                            + " from system uid " + UserHandle.formatUid(callingUid)
20885                            + " pkg " + callerPackage,
20886                    new Throwable());
20887        }
20888    }
20889
20890    @GuardedBy("this")
20891    final int broadcastIntentLocked(ProcessRecord callerApp,
20892            String callerPackage, Intent intent, String resolvedType,
20893            IIntentReceiver resultTo, int resultCode, String resultData,
20894            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
20895            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
20896        intent = new Intent(intent);
20897
20898        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
20899        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
20900        if (callerInstantApp) {
20901            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20902        }
20903
20904        // By default broadcasts do not go to stopped apps.
20905        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
20906
20907        // If we have not finished booting, don't allow this to launch new processes.
20908        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
20909            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20910        }
20911
20912        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
20913                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
20914                + " ordered=" + ordered + " userid=" + userId);
20915        if ((resultTo != null) && !ordered) {
20916            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
20917        }
20918
20919        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20920                ALLOW_NON_FULL, "broadcast", callerPackage);
20921
20922        // Make sure that the user who is receiving this broadcast or its parent is running.
20923        // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
20924        if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
20925            if ((callingUid != SYSTEM_UID
20926                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
20927                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
20928                Slog.w(TAG, "Skipping broadcast of " + intent
20929                        + ": user " + userId + " and its parent (if any) are stopped");
20930                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
20931            }
20932        }
20933
20934        BroadcastOptions brOptions = null;
20935        if (bOptions != null) {
20936            brOptions = new BroadcastOptions(bOptions);
20937            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
20938                // See if the caller is allowed to do this.  Note we are checking against
20939                // the actual real caller (not whoever provided the operation as say a
20940                // PendingIntent), because that who is actually supplied the arguments.
20941                if (checkComponentPermission(
20942                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
20943                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
20944                        != PackageManager.PERMISSION_GRANTED) {
20945                    String msg = "Permission Denial: " + intent.getAction()
20946                            + " broadcast from " + callerPackage + " (pid=" + callingPid
20947                            + ", uid=" + callingUid + ")"
20948                            + " requires "
20949                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
20950                    Slog.w(TAG, msg);
20951                    throw new SecurityException(msg);
20952                }
20953            }
20954        }
20955
20956        // Verify that protected broadcasts are only being sent by system code,
20957        // and that system code is only sending protected broadcasts.
20958        final String action = intent.getAction();
20959        final boolean isProtectedBroadcast;
20960        try {
20961            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
20962        } catch (RemoteException e) {
20963            Slog.w(TAG, "Remote exception", e);
20964            return ActivityManager.BROADCAST_SUCCESS;
20965        }
20966
20967        final boolean isCallerSystem;
20968        switch (UserHandle.getAppId(callingUid)) {
20969            case ROOT_UID:
20970            case SYSTEM_UID:
20971            case PHONE_UID:
20972            case BLUETOOTH_UID:
20973            case NFC_UID:
20974            case SE_UID:
20975                isCallerSystem = true;
20976                break;
20977            default:
20978                isCallerSystem = (callerApp != null) && callerApp.persistent;
20979                break;
20980        }
20981
20982        // First line security check before anything else: stop non-system apps from
20983        // sending protected broadcasts.
20984        if (!isCallerSystem) {
20985            if (isProtectedBroadcast) {
20986                String msg = "Permission Denial: not allowed to send broadcast "
20987                        + action + " from pid="
20988                        + callingPid + ", uid=" + callingUid;
20989                Slog.w(TAG, msg);
20990                throw new SecurityException(msg);
20991
20992            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
20993                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
20994                // Special case for compatibility: we don't want apps to send this,
20995                // but historically it has not been protected and apps may be using it
20996                // to poke their own app widget.  So, instead of making it protected,
20997                // just limit it to the caller.
20998                if (callerPackage == null) {
20999                    String msg = "Permission Denial: not allowed to send broadcast "
21000                            + action + " from unknown caller.";
21001                    Slog.w(TAG, msg);
21002                    throw new SecurityException(msg);
21003                } else if (intent.getComponent() != null) {
21004                    // They are good enough to send to an explicit component...  verify
21005                    // it is being sent to the calling app.
21006                    if (!intent.getComponent().getPackageName().equals(
21007                            callerPackage)) {
21008                        String msg = "Permission Denial: not allowed to send broadcast "
21009                                + action + " to "
21010                                + intent.getComponent().getPackageName() + " from "
21011                                + callerPackage;
21012                        Slog.w(TAG, msg);
21013                        throw new SecurityException(msg);
21014                    }
21015                } else {
21016                    // Limit broadcast to their own package.
21017                    intent.setPackage(callerPackage);
21018                }
21019            }
21020        }
21021
21022        if (action != null) {
21023            if (getBackgroundLaunchBroadcasts().contains(action)) {
21024                if (DEBUG_BACKGROUND_CHECK) {
21025                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
21026                }
21027                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
21028            }
21029
21030            switch (action) {
21031                case Intent.ACTION_UID_REMOVED:
21032                case Intent.ACTION_PACKAGE_REMOVED:
21033                case Intent.ACTION_PACKAGE_CHANGED:
21034                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21035                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21036                case Intent.ACTION_PACKAGES_SUSPENDED:
21037                case Intent.ACTION_PACKAGES_UNSUSPENDED:
21038                    // Handle special intents: if this broadcast is from the package
21039                    // manager about a package being removed, we need to remove all of
21040                    // its activities from the history stack.
21041                    if (checkComponentPermission(
21042                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
21043                            callingPid, callingUid, -1, true)
21044                            != PackageManager.PERMISSION_GRANTED) {
21045                        String msg = "Permission Denial: " + intent.getAction()
21046                                + " broadcast from " + callerPackage + " (pid=" + callingPid
21047                                + ", uid=" + callingUid + ")"
21048                                + " requires "
21049                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
21050                        Slog.w(TAG, msg);
21051                        throw new SecurityException(msg);
21052                    }
21053                    switch (action) {
21054                        case Intent.ACTION_UID_REMOVED:
21055                            final int uid = getUidFromIntent(intent);
21056                            if (uid >= 0) {
21057                                mBatteryStatsService.removeUid(uid);
21058                                mAppOpsService.uidRemoved(uid);
21059                            }
21060                            break;
21061                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21062                            // If resources are unavailable just force stop all those packages
21063                            // and flush the attribute cache as well.
21064                            String list[] =
21065                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21066                            if (list != null && list.length > 0) {
21067                                for (int i = 0; i < list.length; i++) {
21068                                    forceStopPackageLocked(list[i], -1, false, true, true,
21069                                            false, false, userId, "storage unmount");
21070                                }
21071                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21072                                sendPackageBroadcastLocked(
21073                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
21074                                        list, userId);
21075                            }
21076                            break;
21077                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21078                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21079                            break;
21080                        case Intent.ACTION_PACKAGE_REMOVED:
21081                        case Intent.ACTION_PACKAGE_CHANGED:
21082                            Uri data = intent.getData();
21083                            String ssp;
21084                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
21085                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
21086                                final boolean replacing =
21087                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21088                                final boolean killProcess =
21089                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
21090                                final boolean fullUninstall = removed && !replacing;
21091                                if (removed) {
21092                                    if (killProcess) {
21093                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
21094                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
21095                                                false, true, true, false, fullUninstall, userId,
21096                                                removed ? "pkg removed" : "pkg changed");
21097                                    }
21098                                    final int cmd = killProcess
21099                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
21100                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
21101                                    sendPackageBroadcastLocked(cmd,
21102                                            new String[] {ssp}, userId);
21103                                    if (fullUninstall) {
21104                                        mAppOpsService.packageRemoved(
21105                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
21106
21107                                        // Remove all permissions granted from/to this package
21108                                        removeUriPermissionsForPackageLocked(ssp, userId, true,
21109                                                false);
21110
21111                                        mRecentTasks.removeTasksByPackageName(ssp, userId);
21112
21113                                        mServices.forceStopPackageLocked(ssp, userId);
21114                                        mAppWarnings.onPackageUninstalled(ssp);
21115                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
21116                                        mBatteryStatsService.notePackageUninstalled(ssp);
21117                                    }
21118                                } else {
21119                                    if (killProcess) {
21120                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
21121                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
21122                                                userId, ProcessList.INVALID_ADJ,
21123                                                false, true, true, false, "change " + ssp);
21124                                    }
21125                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
21126                                            intent.getStringArrayExtra(
21127                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
21128                                }
21129                            }
21130                            break;
21131                        case Intent.ACTION_PACKAGES_SUSPENDED:
21132                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
21133                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
21134                                    intent.getAction());
21135                            final String[] packageNames = intent.getStringArrayExtra(
21136                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
21137                            final int userHandle = intent.getIntExtra(
21138                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
21139
21140                            synchronized(ActivityManagerService.this) {
21141                                mRecentTasks.onPackagesSuspendedChanged(
21142                                        packageNames, suspended, userHandle);
21143                            }
21144                            break;
21145                    }
21146                    break;
21147                case Intent.ACTION_PACKAGE_REPLACED:
21148                {
21149                    final Uri data = intent.getData();
21150                    final String ssp;
21151                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21152                        ApplicationInfo aInfo = null;
21153                        try {
21154                            aInfo = AppGlobals.getPackageManager()
21155                                    .getApplicationInfo(ssp, 0 /*flags*/, userId);
21156                        } catch (RemoteException ignore) {}
21157                        if (aInfo == null) {
21158                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
21159                                    + " ssp=" + ssp + " data=" + data);
21160                            return ActivityManager.BROADCAST_SUCCESS;
21161                        }
21162                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
21163                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
21164                                new String[] {ssp}, userId);
21165                    }
21166                    break;
21167                }
21168                case Intent.ACTION_PACKAGE_ADDED:
21169                {
21170                    // Special case for adding a package: by default turn on compatibility mode.
21171                    Uri data = intent.getData();
21172                    String ssp;
21173                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21174                        final boolean replacing =
21175                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21176                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
21177
21178                        try {
21179                            ApplicationInfo ai = AppGlobals.getPackageManager().
21180                                    getApplicationInfo(ssp, 0, 0);
21181                            mBatteryStatsService.notePackageInstalled(ssp,
21182                                    ai != null ? ai.versionCode : 0);
21183                        } catch (RemoteException e) {
21184                        }
21185                    }
21186                    break;
21187                }
21188                case Intent.ACTION_PACKAGE_DATA_CLEARED:
21189                {
21190                    Uri data = intent.getData();
21191                    String ssp;
21192                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21193                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
21194                        mAppWarnings.onPackageDataCleared(ssp);
21195                    }
21196                    break;
21197                }
21198                case Intent.ACTION_TIMEZONE_CHANGED:
21199                    // If this is the time zone changed action, queue up a message that will reset
21200                    // the timezone of all currently running processes. This message will get
21201                    // queued up before the broadcast happens.
21202                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
21203                    break;
21204                case Intent.ACTION_TIME_CHANGED:
21205                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
21206                    // the tri-state value it may contain and "unknown".
21207                    // For convenience we re-use the Intent extra values.
21208                    final int NO_EXTRA_VALUE_FOUND = -1;
21209                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
21210                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
21211                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
21212                    // Only send a message if the time preference is available.
21213                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
21214                        Message updateTimePreferenceMsg =
21215                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
21216                                        timeFormatPreferenceMsgValue, 0);
21217                        mHandler.sendMessage(updateTimePreferenceMsg);
21218                    }
21219                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21220                    synchronized (stats) {
21221                        stats.noteCurrentTimeChangedLocked();
21222                    }
21223                    break;
21224                case Intent.ACTION_CLEAR_DNS_CACHE:
21225                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
21226                    break;
21227                case Proxy.PROXY_CHANGE_ACTION:
21228                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
21229                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
21230                    break;
21231                case android.hardware.Camera.ACTION_NEW_PICTURE:
21232                case android.hardware.Camera.ACTION_NEW_VIDEO:
21233                    // In N we just turned these off; in O we are turing them back on partly,
21234                    // only for registered receivers.  This will still address the main problem
21235                    // (a spam of apps waking up when a picture is taken putting significant
21236                    // memory pressure on the system at a bad point), while still allowing apps
21237                    // that are already actively running to know about this happening.
21238                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21239                    break;
21240                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
21241                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
21242                    break;
21243                case "com.android.launcher.action.INSTALL_SHORTCUT":
21244                    // As of O, we no longer support this broadcasts, even for pre-O apps.
21245                    // Apps should now be using ShortcutManager.pinRequestShortcut().
21246                    Log.w(TAG, "Broadcast " + action
21247                            + " no longer supported. It will not be delivered.");
21248                    return ActivityManager.BROADCAST_SUCCESS;
21249            }
21250
21251            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
21252                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
21253                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
21254                final int uid = getUidFromIntent(intent);
21255                if (uid != -1) {
21256                    final UidRecord uidRec = mActiveUids.get(uid);
21257                    if (uidRec != null) {
21258                        uidRec.updateHasInternetPermission();
21259                    }
21260                }
21261            }
21262        }
21263
21264        // Add to the sticky list if requested.
21265        if (sticky) {
21266            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
21267                    callingPid, callingUid)
21268                    != PackageManager.PERMISSION_GRANTED) {
21269                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
21270                        + callingPid + ", uid=" + callingUid
21271                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21272                Slog.w(TAG, msg);
21273                throw new SecurityException(msg);
21274            }
21275            if (requiredPermissions != null && requiredPermissions.length > 0) {
21276                Slog.w(TAG, "Can't broadcast sticky intent " + intent
21277                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
21278                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
21279            }
21280            if (intent.getComponent() != null) {
21281                throw new SecurityException(
21282                        "Sticky broadcasts can't target a specific component");
21283            }
21284            // We use userId directly here, since the "all" target is maintained
21285            // as a separate set of sticky broadcasts.
21286            if (userId != UserHandle.USER_ALL) {
21287                // But first, if this is not a broadcast to all users, then
21288                // make sure it doesn't conflict with an existing broadcast to
21289                // all users.
21290                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
21291                        UserHandle.USER_ALL);
21292                if (stickies != null) {
21293                    ArrayList<Intent> list = stickies.get(intent.getAction());
21294                    if (list != null) {
21295                        int N = list.size();
21296                        int i;
21297                        for (i=0; i<N; i++) {
21298                            if (intent.filterEquals(list.get(i))) {
21299                                throw new IllegalArgumentException(
21300                                        "Sticky broadcast " + intent + " for user "
21301                                        + userId + " conflicts with existing global broadcast");
21302                            }
21303                        }
21304                    }
21305                }
21306            }
21307            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21308            if (stickies == null) {
21309                stickies = new ArrayMap<>();
21310                mStickyBroadcasts.put(userId, stickies);
21311            }
21312            ArrayList<Intent> list = stickies.get(intent.getAction());
21313            if (list == null) {
21314                list = new ArrayList<>();
21315                stickies.put(intent.getAction(), list);
21316            }
21317            final int stickiesCount = list.size();
21318            int i;
21319            for (i = 0; i < stickiesCount; i++) {
21320                if (intent.filterEquals(list.get(i))) {
21321                    // This sticky already exists, replace it.
21322                    list.set(i, new Intent(intent));
21323                    break;
21324                }
21325            }
21326            if (i >= stickiesCount) {
21327                list.add(new Intent(intent));
21328            }
21329        }
21330
21331        int[] users;
21332        if (userId == UserHandle.USER_ALL) {
21333            // Caller wants broadcast to go to all started users.
21334            users = mUserController.getStartedUserArray();
21335        } else {
21336            // Caller wants broadcast to go to one specific user.
21337            users = new int[] {userId};
21338        }
21339
21340        // Figure out who all will receive this broadcast.
21341        List receivers = null;
21342        List<BroadcastFilter> registeredReceivers = null;
21343        // Need to resolve the intent to interested receivers...
21344        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
21345                 == 0) {
21346            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
21347        }
21348        if (intent.getComponent() == null) {
21349            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
21350                // Query one target user at a time, excluding shell-restricted users
21351                for (int i = 0; i < users.length; i++) {
21352                    if (mUserController.hasUserRestriction(
21353                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
21354                        continue;
21355                    }
21356                    List<BroadcastFilter> registeredReceiversForUser =
21357                            mReceiverResolver.queryIntent(intent,
21358                                    resolvedType, false /*defaultOnly*/, users[i]);
21359                    if (registeredReceivers == null) {
21360                        registeredReceivers = registeredReceiversForUser;
21361                    } else if (registeredReceiversForUser != null) {
21362                        registeredReceivers.addAll(registeredReceiversForUser);
21363                    }
21364                }
21365            } else {
21366                registeredReceivers = mReceiverResolver.queryIntent(intent,
21367                        resolvedType, false /*defaultOnly*/, userId);
21368            }
21369        }
21370
21371        final boolean replacePending =
21372                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
21373
21374        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
21375                + " replacePending=" + replacePending);
21376
21377        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
21378        if (!ordered && NR > 0) {
21379            // If we are not serializing this broadcast, then send the
21380            // registered receivers separately so they don't wait for the
21381            // components to be launched.
21382            if (isCallerSystem) {
21383                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21384                        isProtectedBroadcast, registeredReceivers);
21385            }
21386            final BroadcastQueue queue = broadcastQueueForIntent(intent);
21387            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21388                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21389                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
21390                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
21391            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
21392            final boolean replaced = replacePending
21393                    && (queue.replaceParallelBroadcastLocked(r) != null);
21394            // Note: We assume resultTo is null for non-ordered broadcasts.
21395            if (!replaced) {
21396                queue.enqueueParallelBroadcastLocked(r);
21397                queue.scheduleBroadcastsLocked();
21398            }
21399            registeredReceivers = null;
21400            NR = 0;
21401        }
21402
21403        // Merge into one list.
21404        int ir = 0;
21405        if (receivers != null) {
21406            // A special case for PACKAGE_ADDED: do not allow the package
21407            // being added to see this broadcast.  This prevents them from
21408            // using this as a back door to get run as soon as they are
21409            // installed.  Maybe in the future we want to have a special install
21410            // broadcast or such for apps, but we'd like to deliberately make
21411            // this decision.
21412            String skipPackages[] = null;
21413            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
21414                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
21415                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
21416                Uri data = intent.getData();
21417                if (data != null) {
21418                    String pkgName = data.getSchemeSpecificPart();
21419                    if (pkgName != null) {
21420                        skipPackages = new String[] { pkgName };
21421                    }
21422                }
21423            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
21424                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21425            }
21426            if (skipPackages != null && (skipPackages.length > 0)) {
21427                for (String skipPackage : skipPackages) {
21428                    if (skipPackage != null) {
21429                        int NT = receivers.size();
21430                        for (int it=0; it<NT; it++) {
21431                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
21432                            if (curt.activityInfo.packageName.equals(skipPackage)) {
21433                                receivers.remove(it);
21434                                it--;
21435                                NT--;
21436                            }
21437                        }
21438                    }
21439                }
21440            }
21441
21442            int NT = receivers != null ? receivers.size() : 0;
21443            int it = 0;
21444            ResolveInfo curt = null;
21445            BroadcastFilter curr = null;
21446            while (it < NT && ir < NR) {
21447                if (curt == null) {
21448                    curt = (ResolveInfo)receivers.get(it);
21449                }
21450                if (curr == null) {
21451                    curr = registeredReceivers.get(ir);
21452                }
21453                if (curr.getPriority() >= curt.priority) {
21454                    // Insert this broadcast record into the final list.
21455                    receivers.add(it, curr);
21456                    ir++;
21457                    curr = null;
21458                    it++;
21459                    NT++;
21460                } else {
21461                    // Skip to the next ResolveInfo in the final list.
21462                    it++;
21463                    curt = null;
21464                }
21465            }
21466        }
21467        while (ir < NR) {
21468            if (receivers == null) {
21469                receivers = new ArrayList();
21470            }
21471            receivers.add(registeredReceivers.get(ir));
21472            ir++;
21473        }
21474
21475        if (isCallerSystem) {
21476            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21477                    isProtectedBroadcast, receivers);
21478        }
21479
21480        if ((receivers != null && receivers.size() > 0)
21481                || resultTo != null) {
21482            BroadcastQueue queue = broadcastQueueForIntent(intent);
21483            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21484                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21485                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
21486                    resultData, resultExtras, ordered, sticky, false, userId);
21487
21488            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
21489                    + ": prev had " + queue.mOrderedBroadcasts.size());
21490            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
21491                    "Enqueueing broadcast " + r.intent.getAction());
21492
21493            final BroadcastRecord oldRecord =
21494                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
21495            if (oldRecord != null) {
21496                // Replaced, fire the result-to receiver.
21497                if (oldRecord.resultTo != null) {
21498                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
21499                    try {
21500                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
21501                                oldRecord.intent,
21502                                Activity.RESULT_CANCELED, null, null,
21503                                false, false, oldRecord.userId);
21504                    } catch (RemoteException e) {
21505                        Slog.w(TAG, "Failure ["
21506                                + queue.mQueueName + "] sending broadcast result of "
21507                                + intent, e);
21508
21509                    }
21510                }
21511            } else {
21512                queue.enqueueOrderedBroadcastLocked(r);
21513                queue.scheduleBroadcastsLocked();
21514            }
21515        } else {
21516            // There was nobody interested in the broadcast, but we still want to record
21517            // that it happened.
21518            if (intent.getComponent() == null && intent.getPackage() == null
21519                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21520                // This was an implicit broadcast... let's record it for posterity.
21521                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
21522            }
21523        }
21524
21525        return ActivityManager.BROADCAST_SUCCESS;
21526    }
21527
21528    /**
21529     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
21530     */
21531    private int getUidFromIntent(Intent intent) {
21532        if (intent == null) {
21533            return -1;
21534        }
21535        final Bundle intentExtras = intent.getExtras();
21536        return intent.hasExtra(Intent.EXTRA_UID)
21537                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
21538    }
21539
21540    final void rotateBroadcastStatsIfNeededLocked() {
21541        final long now = SystemClock.elapsedRealtime();
21542        if (mCurBroadcastStats == null ||
21543                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
21544            mLastBroadcastStats = mCurBroadcastStats;
21545            if (mLastBroadcastStats != null) {
21546                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
21547                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
21548            }
21549            mCurBroadcastStats = new BroadcastStats();
21550        }
21551    }
21552
21553    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
21554            int skipCount, long dispatchTime) {
21555        rotateBroadcastStatsIfNeededLocked();
21556        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
21557    }
21558
21559    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
21560        rotateBroadcastStatsIfNeededLocked();
21561        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
21562    }
21563
21564    final Intent verifyBroadcastLocked(Intent intent) {
21565        // Refuse possible leaked file descriptors
21566        if (intent != null && intent.hasFileDescriptors() == true) {
21567            throw new IllegalArgumentException("File descriptors passed in Intent");
21568        }
21569
21570        int flags = intent.getFlags();
21571
21572        if (!mProcessesReady) {
21573            // if the caller really truly claims to know what they're doing, go
21574            // ahead and allow the broadcast without launching any receivers
21575            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
21576                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
21577            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21578                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
21579                        + " before boot completion");
21580                throw new IllegalStateException("Cannot broadcast before boot completed");
21581            }
21582        }
21583
21584        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
21585            throw new IllegalArgumentException(
21586                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
21587        }
21588
21589        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21590            switch (Binder.getCallingUid()) {
21591                case ROOT_UID:
21592                case SHELL_UID:
21593                    break;
21594                default:
21595                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
21596                            + Binder.getCallingUid());
21597                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
21598                    break;
21599            }
21600        }
21601
21602        return intent;
21603    }
21604
21605    public final int broadcastIntent(IApplicationThread caller,
21606            Intent intent, String resolvedType, IIntentReceiver resultTo,
21607            int resultCode, String resultData, Bundle resultExtras,
21608            String[] requiredPermissions, int appOp, Bundle bOptions,
21609            boolean serialized, boolean sticky, int userId) {
21610        enforceNotIsolatedCaller("broadcastIntent");
21611        synchronized(this) {
21612            intent = verifyBroadcastLocked(intent);
21613
21614            final ProcessRecord callerApp = getRecordForAppLocked(caller);
21615            final int callingPid = Binder.getCallingPid();
21616            final int callingUid = Binder.getCallingUid();
21617            final long origId = Binder.clearCallingIdentity();
21618            int res = broadcastIntentLocked(callerApp,
21619                    callerApp != null ? callerApp.info.packageName : null,
21620                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
21621                    requiredPermissions, appOp, bOptions, serialized, sticky,
21622                    callingPid, callingUid, userId);
21623            Binder.restoreCallingIdentity(origId);
21624            return res;
21625        }
21626    }
21627
21628
21629    int broadcastIntentInPackage(String packageName, int uid,
21630            Intent intent, String resolvedType, IIntentReceiver resultTo,
21631            int resultCode, String resultData, Bundle resultExtras,
21632            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
21633            int userId) {
21634        synchronized(this) {
21635            intent = verifyBroadcastLocked(intent);
21636
21637            final long origId = Binder.clearCallingIdentity();
21638            String[] requiredPermissions = requiredPermission == null ? null
21639                    : new String[] {requiredPermission};
21640            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
21641                    resultTo, resultCode, resultData, resultExtras,
21642                    requiredPermissions, OP_NONE, bOptions, serialized,
21643                    sticky, -1, uid, userId);
21644            Binder.restoreCallingIdentity(origId);
21645            return res;
21646        }
21647    }
21648
21649    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
21650        // Refuse possible leaked file descriptors
21651        if (intent != null && intent.hasFileDescriptors() == true) {
21652            throw new IllegalArgumentException("File descriptors passed in Intent");
21653        }
21654
21655        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21656                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
21657
21658        synchronized(this) {
21659            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
21660                    != PackageManager.PERMISSION_GRANTED) {
21661                String msg = "Permission Denial: unbroadcastIntent() from pid="
21662                        + Binder.getCallingPid()
21663                        + ", uid=" + Binder.getCallingUid()
21664                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21665                Slog.w(TAG, msg);
21666                throw new SecurityException(msg);
21667            }
21668            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21669            if (stickies != null) {
21670                ArrayList<Intent> list = stickies.get(intent.getAction());
21671                if (list != null) {
21672                    int N = list.size();
21673                    int i;
21674                    for (i=0; i<N; i++) {
21675                        if (intent.filterEquals(list.get(i))) {
21676                            list.remove(i);
21677                            break;
21678                        }
21679                    }
21680                    if (list.size() <= 0) {
21681                        stickies.remove(intent.getAction());
21682                    }
21683                }
21684                if (stickies.size() <= 0) {
21685                    mStickyBroadcasts.remove(userId);
21686                }
21687            }
21688        }
21689    }
21690
21691    void backgroundServicesFinishedLocked(int userId) {
21692        for (BroadcastQueue queue : mBroadcastQueues) {
21693            queue.backgroundServicesFinishedLocked(userId);
21694        }
21695    }
21696
21697    public void finishReceiver(IBinder who, int resultCode, String resultData,
21698            Bundle resultExtras, boolean resultAbort, int flags) {
21699        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
21700
21701        // Refuse possible leaked file descriptors
21702        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
21703            throw new IllegalArgumentException("File descriptors passed in Bundle");
21704        }
21705
21706        final long origId = Binder.clearCallingIdentity();
21707        try {
21708            boolean doNext = false;
21709            BroadcastRecord r;
21710
21711            synchronized(this) {
21712                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
21713                        ? mFgBroadcastQueue : mBgBroadcastQueue;
21714                r = queue.getMatchingOrderedReceiver(who);
21715                if (r != null) {
21716                    doNext = r.queue.finishReceiverLocked(r, resultCode,
21717                        resultData, resultExtras, resultAbort, true);
21718                }
21719            }
21720
21721            if (doNext) {
21722                r.queue.processNextBroadcast(false);
21723            }
21724            trimApplications();
21725        } finally {
21726            Binder.restoreCallingIdentity(origId);
21727        }
21728    }
21729
21730    // =========================================================
21731    // INSTRUMENTATION
21732    // =========================================================
21733
21734    public boolean startInstrumentation(ComponentName className,
21735            String profileFile, int flags, Bundle arguments,
21736            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
21737            int userId, String abiOverride) {
21738        enforceNotIsolatedCaller("startInstrumentation");
21739        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21740                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
21741        // Refuse possible leaked file descriptors
21742        if (arguments != null && arguments.hasFileDescriptors()) {
21743            throw new IllegalArgumentException("File descriptors passed in Bundle");
21744        }
21745
21746        synchronized(this) {
21747            InstrumentationInfo ii = null;
21748            ApplicationInfo ai = null;
21749            try {
21750                ii = mContext.getPackageManager().getInstrumentationInfo(
21751                    className, STOCK_PM_FLAGS);
21752                ai = AppGlobals.getPackageManager().getApplicationInfo(
21753                        ii.targetPackage, STOCK_PM_FLAGS, userId);
21754            } catch (PackageManager.NameNotFoundException e) {
21755            } catch (RemoteException e) {
21756            }
21757            if (ii == null) {
21758                reportStartInstrumentationFailureLocked(watcher, className,
21759                        "Unable to find instrumentation info for: " + className);
21760                return false;
21761            }
21762            if (ai == null) {
21763                reportStartInstrumentationFailureLocked(watcher, className,
21764                        "Unable to find instrumentation target package: " + ii.targetPackage);
21765                return false;
21766            }
21767            if (!ai.hasCode()) {
21768                reportStartInstrumentationFailureLocked(watcher, className,
21769                        "Instrumentation target has no code: " + ii.targetPackage);
21770                return false;
21771            }
21772
21773            int match = mContext.getPackageManager().checkSignatures(
21774                    ii.targetPackage, ii.packageName);
21775            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
21776                String msg = "Permission Denial: starting instrumentation "
21777                        + className + " from pid="
21778                        + Binder.getCallingPid()
21779                        + ", uid=" + Binder.getCallingPid()
21780                        + " not allowed because package " + ii.packageName
21781                        + " does not have a signature matching the target "
21782                        + ii.targetPackage;
21783                reportStartInstrumentationFailureLocked(watcher, className, msg);
21784                throw new SecurityException(msg);
21785            }
21786
21787            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
21788            activeInstr.mClass = className;
21789            String defProcess = ai.processName;;
21790            if (ii.targetProcesses == null) {
21791                activeInstr.mTargetProcesses = new String[]{ai.processName};
21792            } else if (ii.targetProcesses.equals("*")) {
21793                activeInstr.mTargetProcesses = new String[0];
21794            } else {
21795                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
21796                defProcess = activeInstr.mTargetProcesses[0];
21797            }
21798            activeInstr.mTargetInfo = ai;
21799            activeInstr.mProfileFile = profileFile;
21800            activeInstr.mArguments = arguments;
21801            activeInstr.mWatcher = watcher;
21802            activeInstr.mUiAutomationConnection = uiAutomationConnection;
21803            activeInstr.mResultClass = className;
21804
21805            final long origId = Binder.clearCallingIdentity();
21806            // Instrumentation can kill and relaunch even persistent processes
21807            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
21808                    "start instr");
21809            // Inform usage stats to make the target package active
21810            if (mUsageStatsService != null) {
21811                mUsageStatsService.reportEvent(ii.targetPackage, userId,
21812                        UsageEvents.Event.SYSTEM_INTERACTION);
21813            }
21814            boolean disableHiddenApiChecks =
21815                    (flags & INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
21816            ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
21817                    abiOverride);
21818            app.instr = activeInstr;
21819            activeInstr.mFinished = false;
21820            activeInstr.mRunningProcesses.add(app);
21821            if (!mActiveInstrumentation.contains(activeInstr)) {
21822                mActiveInstrumentation.add(activeInstr);
21823            }
21824            Binder.restoreCallingIdentity(origId);
21825        }
21826
21827        return true;
21828    }
21829
21830    /**
21831     * Report errors that occur while attempting to start Instrumentation.  Always writes the
21832     * error to the logs, but if somebody is watching, send the report there too.  This enables
21833     * the "am" command to report errors with more information.
21834     *
21835     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
21836     * @param cn The component name of the instrumentation.
21837     * @param report The error report.
21838     */
21839    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
21840            ComponentName cn, String report) {
21841        Slog.w(TAG, report);
21842        if (watcher != null) {
21843            Bundle results = new Bundle();
21844            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
21845            results.putString("Error", report);
21846            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
21847        }
21848    }
21849
21850    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
21851        if (app.instr == null) {
21852            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
21853            return;
21854        }
21855
21856        if (!app.instr.mFinished && results != null) {
21857            if (app.instr.mCurResults == null) {
21858                app.instr.mCurResults = new Bundle(results);
21859            } else {
21860                app.instr.mCurResults.putAll(results);
21861            }
21862        }
21863    }
21864
21865    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
21866        int userId = UserHandle.getCallingUserId();
21867        // Refuse possible leaked file descriptors
21868        if (results != null && results.hasFileDescriptors()) {
21869            throw new IllegalArgumentException("File descriptors passed in Intent");
21870        }
21871
21872        synchronized(this) {
21873            ProcessRecord app = getRecordForAppLocked(target);
21874            if (app == null) {
21875                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
21876                return;
21877            }
21878            final long origId = Binder.clearCallingIdentity();
21879            addInstrumentationResultsLocked(app, results);
21880            Binder.restoreCallingIdentity(origId);
21881        }
21882    }
21883
21884    @GuardedBy("this")
21885    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
21886        if (app.instr == null) {
21887            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
21888            return;
21889        }
21890
21891        if (!app.instr.mFinished) {
21892            if (app.instr.mWatcher != null) {
21893                Bundle finalResults = app.instr.mCurResults;
21894                if (finalResults != null) {
21895                    if (app.instr.mCurResults != null && results != null) {
21896                        finalResults.putAll(results);
21897                    }
21898                } else {
21899                    finalResults = results;
21900                }
21901                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
21902                        app.instr.mClass, resultCode, finalResults);
21903            }
21904
21905            // Can't call out of the system process with a lock held, so post a message.
21906            if (app.instr.mUiAutomationConnection != null) {
21907                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
21908                        app.instr.mUiAutomationConnection).sendToTarget();
21909            }
21910            app.instr.mFinished = true;
21911        }
21912
21913        app.instr.removeProcess(app);
21914        app.instr = null;
21915
21916        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
21917                "finished inst");
21918    }
21919
21920    public void finishInstrumentation(IApplicationThread target,
21921            int resultCode, Bundle results) {
21922        int userId = UserHandle.getCallingUserId();
21923        // Refuse possible leaked file descriptors
21924        if (results != null && results.hasFileDescriptors()) {
21925            throw new IllegalArgumentException("File descriptors passed in Intent");
21926        }
21927
21928        synchronized(this) {
21929            ProcessRecord app = getRecordForAppLocked(target);
21930            if (app == null) {
21931                Slog.w(TAG, "finishInstrumentation: no app for " + target);
21932                return;
21933            }
21934            final long origId = Binder.clearCallingIdentity();
21935            finishInstrumentationLocked(app, resultCode, results);
21936            Binder.restoreCallingIdentity(origId);
21937        }
21938    }
21939
21940    // =========================================================
21941    // CONFIGURATION
21942    // =========================================================
21943
21944    public ConfigurationInfo getDeviceConfigurationInfo() {
21945        ConfigurationInfo config = new ConfigurationInfo();
21946        synchronized (this) {
21947            final Configuration globalConfig = getGlobalConfiguration();
21948            config.reqTouchScreen = globalConfig.touchscreen;
21949            config.reqKeyboardType = globalConfig.keyboard;
21950            config.reqNavigation = globalConfig.navigation;
21951            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
21952                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
21953                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
21954            }
21955            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
21956                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
21957                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
21958            }
21959            config.reqGlEsVersion = GL_ES_VERSION;
21960        }
21961        return config;
21962    }
21963
21964    ActivityStack getFocusedStack() {
21965        return mStackSupervisor.getFocusedStack();
21966    }
21967
21968    @Override
21969    public StackInfo getFocusedStackInfo() throws RemoteException {
21970        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
21971        long ident = Binder.clearCallingIdentity();
21972        try {
21973            synchronized (this) {
21974                ActivityStack focusedStack = getFocusedStack();
21975                if (focusedStack != null) {
21976                    return mStackSupervisor.getStackInfo(focusedStack.mStackId);
21977                }
21978                return null;
21979            }
21980        } finally {
21981            Binder.restoreCallingIdentity(ident);
21982        }
21983    }
21984
21985    public Configuration getConfiguration() {
21986        Configuration ci;
21987        synchronized(this) {
21988            ci = new Configuration(getGlobalConfiguration());
21989            ci.userSetLocale = false;
21990        }
21991        return ci;
21992    }
21993
21994    @Override
21995    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
21996        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
21997        synchronized (this) {
21998            mSuppressResizeConfigChanges = suppress;
21999        }
22000    }
22001
22002    /**
22003     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
22004     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
22005     *       activity and clearing the task at the same time.
22006     */
22007    @Override
22008    // TODO: API should just be about changing windowing modes...
22009    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
22010        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
22011                "moveTasksToFullscreenStack()");
22012        synchronized (this) {
22013            final long origId = Binder.clearCallingIdentity();
22014            try {
22015                final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
22016                if (stack != null){
22017                    if (!stack.isActivityTypeStandardOrUndefined()) {
22018                        throw new IllegalArgumentException(
22019                                "You can't move tasks from non-standard stacks.");
22020                    }
22021                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
22022                }
22023            } finally {
22024                Binder.restoreCallingIdentity(origId);
22025            }
22026        }
22027    }
22028
22029    @Override
22030    public void updatePersistentConfiguration(Configuration values) {
22031        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
22032        enforceWriteSettingsPermission("updatePersistentConfiguration()");
22033        if (values == null) {
22034            throw new NullPointerException("Configuration must not be null");
22035        }
22036
22037        int userId = UserHandle.getCallingUserId();
22038
22039        synchronized(this) {
22040            updatePersistentConfigurationLocked(values, userId);
22041        }
22042    }
22043
22044    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
22045        final long origId = Binder.clearCallingIdentity();
22046        try {
22047            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
22048        } finally {
22049            Binder.restoreCallingIdentity(origId);
22050        }
22051    }
22052
22053    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
22054        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
22055                FONT_SCALE, 1.0f, userId);
22056
22057        synchronized (this) {
22058            if (getGlobalConfiguration().fontScale == scaleFactor) {
22059                return;
22060            }
22061
22062            final Configuration configuration
22063                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22064            configuration.fontScale = scaleFactor;
22065            updatePersistentConfigurationLocked(configuration, userId);
22066        }
22067    }
22068
22069    private void enforceWriteSettingsPermission(String func) {
22070        int uid = Binder.getCallingUid();
22071        if (uid == ROOT_UID) {
22072            return;
22073        }
22074
22075        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
22076                Settings.getPackageNameForUid(mContext, uid), false)) {
22077            return;
22078        }
22079
22080        String msg = "Permission Denial: " + func + " from pid="
22081                + Binder.getCallingPid()
22082                + ", uid=" + uid
22083                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
22084        Slog.w(TAG, msg);
22085        throw new SecurityException(msg);
22086    }
22087
22088    @Override
22089    public boolean updateConfiguration(Configuration values) {
22090        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
22091
22092        synchronized(this) {
22093            if (values == null && mWindowManager != null) {
22094                // sentinel: fetch the current configuration from the window manager
22095                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22096            }
22097
22098            if (mWindowManager != null) {
22099                // Update OOM levels based on display size.
22100                mProcessList.applyDisplaySize(mWindowManager);
22101            }
22102
22103            final long origId = Binder.clearCallingIdentity();
22104            try {
22105                if (values != null) {
22106                    Settings.System.clearConfiguration(values);
22107                }
22108                updateConfigurationLocked(values, null, false, false /* persistent */,
22109                        UserHandle.USER_NULL, false /* deferResume */,
22110                        mTmpUpdateConfigurationResult);
22111                return mTmpUpdateConfigurationResult.changes != 0;
22112            } finally {
22113                Binder.restoreCallingIdentity(origId);
22114            }
22115        }
22116    }
22117
22118    void updateUserConfigurationLocked() {
22119        final Configuration configuration = new Configuration(getGlobalConfiguration());
22120        final int currentUserId = mUserController.getCurrentUserId();
22121        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
22122                currentUserId, Settings.System.canWrite(mContext));
22123        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
22124                false /* persistent */, currentUserId, false /* deferResume */);
22125    }
22126
22127    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22128            boolean initLocale) {
22129        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
22130    }
22131
22132    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22133            boolean initLocale, boolean deferResume) {
22134        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
22135        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
22136                UserHandle.USER_NULL, deferResume);
22137    }
22138
22139    // To cache the list of supported system locales
22140    private String[] mSupportedSystemLocales = null;
22141
22142    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22143            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
22144        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
22145                deferResume, null /* result */);
22146    }
22147
22148    /**
22149     * Do either or both things: (1) change the current configuration, and (2)
22150     * make sure the given activity is running with the (now) current
22151     * configuration.  Returns true if the activity has been left running, or
22152     * false if <var>starting</var> is being destroyed to match the new
22153     * configuration.
22154     *
22155     * @param userId is only used when persistent parameter is set to true to persist configuration
22156     *               for that particular user
22157     */
22158    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22159            boolean initLocale, boolean persistent, int userId, boolean deferResume,
22160            UpdateConfigurationResult result) {
22161        int changes = 0;
22162        boolean kept = true;
22163
22164        if (mWindowManager != null) {
22165            mWindowManager.deferSurfaceLayout();
22166        }
22167        try {
22168            if (values != null) {
22169                changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
22170                        deferResume);
22171            }
22172
22173            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22174        } finally {
22175            if (mWindowManager != null) {
22176                mWindowManager.continueSurfaceLayout();
22177            }
22178        }
22179
22180        if (result != null) {
22181            result.changes = changes;
22182            result.activityRelaunched = !kept;
22183        }
22184        return kept;
22185    }
22186
22187    /**
22188     * Returns true if this configuration change is interesting enough to send an
22189     * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
22190     */
22191    private static boolean isSplitConfigurationChange(int configDiff) {
22192        return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
22193    }
22194
22195    /** Update default (global) configuration and notify listeners about changes. */
22196    private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
22197            boolean persistent, int userId, boolean deferResume) {
22198        mTempConfig.setTo(getGlobalConfiguration());
22199        final int changes = mTempConfig.updateFrom(values);
22200        if (changes == 0) {
22201            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
22202            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
22203            // performDisplayOverrideConfigUpdate in order to send the new display configuration
22204            // (even if there are no actual changes) to unfreeze the window.
22205            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
22206            return 0;
22207        }
22208
22209        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
22210                "Updating global configuration to: " + values);
22211
22212        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
22213        StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
22214                values.colorMode,
22215                values.densityDpi,
22216                values.fontScale,
22217                values.hardKeyboardHidden,
22218                values.keyboard,
22219                values.keyboardHidden,
22220                values.mcc,
22221                values.mnc,
22222                values.navigation,
22223                values.navigationHidden,
22224                values.orientation,
22225                values.screenHeightDp,
22226                values.screenLayout,
22227                values.screenWidthDp,
22228                values.smallestScreenWidthDp,
22229                values.touchscreen,
22230                values.uiMode);
22231
22232
22233        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
22234            final LocaleList locales = values.getLocales();
22235            int bestLocaleIndex = 0;
22236            if (locales.size() > 1) {
22237                if (mSupportedSystemLocales == null) {
22238                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
22239                }
22240                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
22241            }
22242            SystemProperties.set("persist.sys.locale",
22243                    locales.get(bestLocaleIndex).toLanguageTag());
22244            LocaleList.setDefault(locales, bestLocaleIndex);
22245            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
22246                    locales.get(bestLocaleIndex)));
22247        }
22248
22249        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
22250        mTempConfig.seq = mConfigurationSeq;
22251
22252        // Update stored global config and notify everyone about the change.
22253        mStackSupervisor.onConfigurationChanged(mTempConfig);
22254
22255        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
22256        // TODO(multi-display): Update UsageEvents#Event to include displayId.
22257        mUsageStatsService.reportConfigurationChange(mTempConfig,
22258                mUserController.getCurrentUserId());
22259
22260        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
22261        mShowDialogs = shouldShowDialogs(mTempConfig);
22262
22263        AttributeCache ac = AttributeCache.instance();
22264        if (ac != null) {
22265            ac.updateConfiguration(mTempConfig);
22266        }
22267
22268        // Make sure all resources in our process are updated right now, so that anyone who is going
22269        // to retrieve resource values after we return will be sure to get the new ones. This is
22270        // especially important during boot, where the first config change needs to guarantee all
22271        // resources have that config before following boot code is executed.
22272        mSystemThread.applyConfigurationToResources(mTempConfig);
22273
22274        // We need another copy of global config because we're scheduling some calls instead of
22275        // running them in place. We need to be sure that object we send will be handled unchanged.
22276        final Configuration configCopy = new Configuration(mTempConfig);
22277        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
22278            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
22279            msg.obj = configCopy;
22280            msg.arg1 = userId;
22281            mHandler.sendMessage(msg);
22282        }
22283
22284        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22285            ProcessRecord app = mLruProcesses.get(i);
22286            try {
22287                if (app.thread != null) {
22288                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
22289                            + app.processName + " new config " + configCopy);
22290                    mLifecycleManager.scheduleTransaction(app.thread,
22291                            ConfigurationChangeItem.obtain(configCopy));
22292                }
22293            } catch (Exception e) {
22294                Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
22295            }
22296        }
22297
22298        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
22299        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
22300                | Intent.FLAG_RECEIVER_FOREGROUND
22301                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22302        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22303                OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22304                UserHandle.USER_ALL);
22305        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
22306            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
22307            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
22308                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
22309                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22310            if (initLocale || !mProcessesReady) {
22311                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
22312            }
22313            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22314                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22315                    UserHandle.USER_ALL);
22316        }
22317
22318        // Send a broadcast to PackageInstallers if the configuration change is interesting
22319        // for the purposes of installing additional splits.
22320        if (!initLocale && isSplitConfigurationChange(changes)) {
22321            intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
22322            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
22323                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
22324
22325            // Typically only app stores will have this permission.
22326            String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
22327            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
22328                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
22329        }
22330
22331        // Override configuration of the default display duplicates global config, so we need to
22332        // update it also. This will also notify WindowManager about changes.
22333        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
22334                DEFAULT_DISPLAY);
22335
22336        return changes;
22337    }
22338
22339    @Override
22340    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
22341        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
22342
22343        synchronized (this) {
22344            // Check if display is initialized in AM.
22345            if (!mStackSupervisor.isDisplayAdded(displayId)) {
22346                // Call might come when display is not yet added or has already been removed.
22347                if (DEBUG_CONFIGURATION) {
22348                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
22349                            + displayId);
22350                }
22351                return false;
22352            }
22353
22354            if (values == null && mWindowManager != null) {
22355                // sentinel: fetch the current configuration from the window manager
22356                values = mWindowManager.computeNewConfiguration(displayId);
22357            }
22358
22359            if (mWindowManager != null) {
22360                // Update OOM levels based on display size.
22361                mProcessList.applyDisplaySize(mWindowManager);
22362            }
22363
22364            final long origId = Binder.clearCallingIdentity();
22365            try {
22366                if (values != null) {
22367                    Settings.System.clearConfiguration(values);
22368                }
22369                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
22370                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
22371                return mTmpUpdateConfigurationResult.changes != 0;
22372            } finally {
22373                Binder.restoreCallingIdentity(origId);
22374            }
22375        }
22376    }
22377
22378    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
22379            boolean deferResume, int displayId) {
22380        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
22381                displayId, null /* result */);
22382    }
22383
22384    /**
22385     * Updates override configuration specific for the selected display. If no config is provided,
22386     * new one will be computed in WM based on current display info.
22387     */
22388    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
22389            ActivityRecord starting, boolean deferResume, int displayId,
22390            UpdateConfigurationResult result) {
22391        int changes = 0;
22392        boolean kept = true;
22393
22394        if (mWindowManager != null) {
22395            mWindowManager.deferSurfaceLayout();
22396        }
22397        try {
22398            if (values != null) {
22399                if (displayId == DEFAULT_DISPLAY) {
22400                    // Override configuration of the default display duplicates global config, so
22401                    // we're calling global config update instead for default display. It will also
22402                    // apply the correct override config.
22403                    changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
22404                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
22405                } else {
22406                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
22407                }
22408            }
22409
22410            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22411        } finally {
22412            if (mWindowManager != null) {
22413                mWindowManager.continueSurfaceLayout();
22414            }
22415        }
22416
22417        if (result != null) {
22418            result.changes = changes;
22419            result.activityRelaunched = !kept;
22420        }
22421        return kept;
22422    }
22423
22424    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
22425            int displayId) {
22426        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
22427        final int changes = mTempConfig.updateFrom(values);
22428        if (changes != 0) {
22429            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
22430                    + mTempConfig + " for displayId=" + displayId);
22431            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
22432
22433            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
22434            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
22435                mAppWarnings.onDensityChanged();
22436
22437                killAllBackgroundProcessesExcept(N,
22438                        ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
22439            }
22440        }
22441
22442        // Update the configuration with WM first and check if any of the stacks need to be resized
22443        // due to the configuration change. If so, resize the stacks now and do any relaunches if
22444        // necessary. This way we don't need to relaunch again afterwards in
22445        // ensureActivityConfiguration().
22446        if (mWindowManager != null) {
22447            final int[] resizedStacks =
22448                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
22449            if (resizedStacks != null) {
22450                for (int stackId : resizedStacks) {
22451                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
22452                }
22453            }
22454        }
22455
22456        return changes;
22457    }
22458
22459    /** Applies latest configuration and/or visibility updates if needed. */
22460    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
22461        boolean kept = true;
22462        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
22463        // mainStack is null during startup.
22464        if (mainStack != null) {
22465            if (changes != 0 && starting == null) {
22466                // If the configuration changed, and the caller is not already
22467                // in the process of starting an activity, then find the top
22468                // activity to check if its configuration needs to change.
22469                starting = mainStack.topRunningActivityLocked();
22470            }
22471
22472            if (starting != null) {
22473                kept = starting.ensureActivityConfiguration(changes,
22474                        false /* preserveWindow */);
22475                // And we need to make sure at this point that all other activities
22476                // are made visible with the correct configuration.
22477                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
22478                        !PRESERVE_WINDOWS);
22479            }
22480        }
22481
22482        return kept;
22483    }
22484
22485    /** Helper method that requests bounds from WM and applies them to stack. */
22486    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
22487        final Rect newStackBounds = new Rect();
22488        final ActivityStack stack = mStackSupervisor.getStack(stackId);
22489
22490        // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
22491        if (stack == null) {
22492            final StringWriter writer = new StringWriter();
22493            final PrintWriter printWriter = new PrintWriter(writer);
22494            mStackSupervisor.dumpDisplays(printWriter);
22495            printWriter.flush();
22496
22497            Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
22498        }
22499
22500        stack.getBoundsForNewConfiguration(newStackBounds);
22501        mStackSupervisor.resizeStackLocked(
22502                stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
22503                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
22504                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
22505    }
22506
22507    /**
22508     * Decide based on the configuration whether we should show the ANR,
22509     * crash, etc dialogs.  The idea is that if there is no affordance to
22510     * press the on-screen buttons, or the user experience would be more
22511     * greatly impacted than the crash itself, we shouldn't show the dialog.
22512     *
22513     * A thought: SystemUI might also want to get told about this, the Power
22514     * dialog / global actions also might want different behaviors.
22515     */
22516    private static boolean shouldShowDialogs(Configuration config) {
22517        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
22518                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
22519                                   && config.navigation == Configuration.NAVIGATION_NONAV);
22520        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
22521        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
22522                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
22523                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
22524                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
22525        return inputMethodExists && uiModeSupportsDialogs;
22526    }
22527
22528    @Override
22529    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
22530        synchronized (this) {
22531            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
22532            if (srec != null) {
22533                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
22534            }
22535        }
22536        return false;
22537    }
22538
22539    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
22540            Intent resultData) {
22541
22542        synchronized (this) {
22543            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
22544            if (r != null) {
22545                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
22546            }
22547            return false;
22548        }
22549    }
22550
22551    public int getLaunchedFromUid(IBinder activityToken) {
22552        ActivityRecord srec;
22553        synchronized (this) {
22554            srec = ActivityRecord.forTokenLocked(activityToken);
22555        }
22556        if (srec == null) {
22557            return -1;
22558        }
22559        return srec.launchedFromUid;
22560    }
22561
22562    public String getLaunchedFromPackage(IBinder activityToken) {
22563        ActivityRecord srec;
22564        synchronized (this) {
22565            srec = ActivityRecord.forTokenLocked(activityToken);
22566        }
22567        if (srec == null) {
22568            return null;
22569        }
22570        return srec.launchedFromPackage;
22571    }
22572
22573    // =========================================================
22574    // LIFETIME MANAGEMENT
22575    // =========================================================
22576
22577    // Returns whether the app is receiving broadcast.
22578    // If receiving, fetch all broadcast queues which the app is
22579    // the current [or imminent] receiver on.
22580    private boolean isReceivingBroadcastLocked(ProcessRecord app,
22581            ArraySet<BroadcastQueue> receivingQueues) {
22582        final int N = app.curReceivers.size();
22583        if (N > 0) {
22584            for (int i = 0; i < N; i++) {
22585                receivingQueues.add(app.curReceivers.valueAt(i).queue);
22586            }
22587            return true;
22588        }
22589
22590        // It's not the current receiver, but it might be starting up to become one
22591        for (BroadcastQueue queue : mBroadcastQueues) {
22592            final BroadcastRecord r = queue.mPendingBroadcast;
22593            if (r != null && r.curApp == app) {
22594                // found it; report which queue it's in
22595                receivingQueues.add(queue);
22596            }
22597        }
22598
22599        return !receivingQueues.isEmpty();
22600    }
22601
22602    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
22603            int targetUid, ComponentName targetComponent, String targetProcess) {
22604        if (!mTrackingAssociations) {
22605            return null;
22606        }
22607        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22608                = mAssociations.get(targetUid);
22609        if (components == null) {
22610            components = new ArrayMap<>();
22611            mAssociations.put(targetUid, components);
22612        }
22613        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22614        if (sourceUids == null) {
22615            sourceUids = new SparseArray<>();
22616            components.put(targetComponent, sourceUids);
22617        }
22618        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22619        if (sourceProcesses == null) {
22620            sourceProcesses = new ArrayMap<>();
22621            sourceUids.put(sourceUid, sourceProcesses);
22622        }
22623        Association ass = sourceProcesses.get(sourceProcess);
22624        if (ass == null) {
22625            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
22626                    targetProcess);
22627            sourceProcesses.put(sourceProcess, ass);
22628        }
22629        ass.mCount++;
22630        ass.mNesting++;
22631        if (ass.mNesting == 1) {
22632            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
22633            ass.mLastState = sourceState;
22634        }
22635        return ass;
22636    }
22637
22638    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
22639            ComponentName targetComponent) {
22640        if (!mTrackingAssociations) {
22641            return;
22642        }
22643        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22644                = mAssociations.get(targetUid);
22645        if (components == null) {
22646            return;
22647        }
22648        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22649        if (sourceUids == null) {
22650            return;
22651        }
22652        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22653        if (sourceProcesses == null) {
22654            return;
22655        }
22656        Association ass = sourceProcesses.get(sourceProcess);
22657        if (ass == null || ass.mNesting <= 0) {
22658            return;
22659        }
22660        ass.mNesting--;
22661        if (ass.mNesting == 0) {
22662            long uptime = SystemClock.uptimeMillis();
22663            ass.mTime += uptime - ass.mStartTime;
22664            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22665                    += uptime - ass.mLastStateUptime;
22666            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
22667        }
22668    }
22669
22670    private void noteUidProcessState(final int uid, final int state) {
22671        mBatteryStatsService.noteUidProcessState(uid, state);
22672        if (mTrackingAssociations) {
22673            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
22674                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
22675                        = mAssociations.valueAt(i1);
22676                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
22677                    SparseArray<ArrayMap<String, Association>> sourceUids
22678                            = targetComponents.valueAt(i2);
22679                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
22680                    if (sourceProcesses != null) {
22681                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
22682                            Association ass = sourceProcesses.valueAt(i4);
22683                            if (ass.mNesting >= 1) {
22684                                // currently associated
22685                                long uptime = SystemClock.uptimeMillis();
22686                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22687                                        += uptime - ass.mLastStateUptime;
22688                                ass.mLastState = state;
22689                                ass.mLastStateUptime = uptime;
22690                            }
22691                        }
22692                    }
22693                }
22694            }
22695        }
22696    }
22697
22698    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
22699            boolean doingAll, long now) {
22700        if (mAdjSeq == app.adjSeq) {
22701            // This adjustment has already been computed.
22702            return app.curRawAdj;
22703        }
22704
22705        if (app.thread == null) {
22706            app.adjSeq = mAdjSeq;
22707            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22708            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22709            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
22710        }
22711
22712        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
22713        app.adjSource = null;
22714        app.adjTarget = null;
22715        app.empty = false;
22716        app.cached = false;
22717
22718        final int activitiesSize = app.activities.size();
22719
22720        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
22721            // The max adjustment doesn't allow this app to be anything
22722            // below foreground, so it is not worth doing work for it.
22723            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
22724            app.adjType = "fixed";
22725            app.adjSeq = mAdjSeq;
22726            app.curRawAdj = app.maxAdj;
22727            app.foregroundActivities = false;
22728            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22729            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
22730            // System processes can do UI, and when they do we want to have
22731            // them trim their memory after the user leaves the UI.  To
22732            // facilitate this, here we need to determine whether or not it
22733            // is currently showing UI.
22734            app.systemNoUi = true;
22735            if (app == TOP_APP) {
22736                app.systemNoUi = false;
22737                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22738                app.adjType = "pers-top-activity";
22739            } else if (app.hasTopUi) {
22740                app.systemNoUi = false;
22741                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22742                app.adjType = "pers-top-ui";
22743            } else if (activitiesSize > 0) {
22744                for (int j = 0; j < activitiesSize; j++) {
22745                    final ActivityRecord r = app.activities.get(j);
22746                    if (r.visible) {
22747                        app.systemNoUi = false;
22748                    }
22749                }
22750            }
22751            if (!app.systemNoUi) {
22752                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
22753            }
22754            return (app.curAdj=app.maxAdj);
22755        }
22756
22757        app.systemNoUi = false;
22758
22759        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
22760
22761        // Determine the importance of the process, starting with most
22762        // important to least, and assign an appropriate OOM adjustment.
22763        int adj;
22764        int schedGroup;
22765        int procState;
22766        boolean foregroundActivities = false;
22767        mTmpBroadcastQueue.clear();
22768        if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
22769            // The last app on the list is the foreground app.
22770            adj = ProcessList.FOREGROUND_APP_ADJ;
22771            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22772            app.adjType = "top-activity";
22773            foregroundActivities = true;
22774            procState = PROCESS_STATE_CUR_TOP;
22775            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
22776        } else if (app.runningRemoteAnimation) {
22777            adj = ProcessList.VISIBLE_APP_ADJ;
22778            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22779            app.adjType = "running-remote-anim";
22780            procState = PROCESS_STATE_CUR_TOP;
22781            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making running remote anim: " + app);
22782        } else if (app.instr != null) {
22783            // Don't want to kill running instrumentation.
22784            adj = ProcessList.FOREGROUND_APP_ADJ;
22785            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22786            app.adjType = "instrumentation";
22787            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
22788            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
22789        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
22790            // An app that is currently receiving a broadcast also
22791            // counts as being in the foreground for OOM killer purposes.
22792            // It's placed in a sched group based on the nature of the
22793            // broadcast as reflected by which queue it's active in.
22794            adj = ProcessList.FOREGROUND_APP_ADJ;
22795            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
22796                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
22797            app.adjType = "broadcast";
22798            procState = ActivityManager.PROCESS_STATE_RECEIVER;
22799            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
22800        } else if (app.executingServices.size() > 0) {
22801            // An app that is currently executing a service callback also
22802            // counts as being in the foreground.
22803            adj = ProcessList.FOREGROUND_APP_ADJ;
22804            schedGroup = app.execServicesFg ?
22805                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
22806            app.adjType = "exec-service";
22807            procState = ActivityManager.PROCESS_STATE_SERVICE;
22808            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
22809            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
22810        } else if (app == TOP_APP) {
22811            adj = ProcessList.FOREGROUND_APP_ADJ;
22812            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22813            app.adjType = "top-sleeping";
22814            foregroundActivities = true;
22815            procState = PROCESS_STATE_CUR_TOP;
22816            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
22817        } else {
22818            // As far as we know the process is empty.  We may change our mind later.
22819            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22820            // At this point we don't actually know the adjustment.  Use the cached adj
22821            // value that the caller wants us to.
22822            adj = cachedAdj;
22823            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22824            app.cached = true;
22825            app.empty = true;
22826            app.adjType = "cch-empty";
22827            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
22828        }
22829
22830        // Examine all activities if not already foreground.
22831        if (!foregroundActivities && activitiesSize > 0) {
22832            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
22833            for (int j = 0; j < activitiesSize; j++) {
22834                final ActivityRecord r = app.activities.get(j);
22835                if (r.app != app) {
22836                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
22837                            + " instead of expected " + app);
22838                    if (r.app == null || (r.app.uid == app.uid)) {
22839                        // Only fix things up when they look sane
22840                        r.setProcess(app);
22841                    } else {
22842                        continue;
22843                    }
22844                }
22845                if (r.visible) {
22846                    // App has a visible activity; only upgrade adjustment.
22847                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
22848                        adj = ProcessList.VISIBLE_APP_ADJ;
22849                        app.adjType = "vis-activity";
22850                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
22851                    }
22852                    if (procState > PROCESS_STATE_CUR_TOP) {
22853                        procState = PROCESS_STATE_CUR_TOP;
22854                        app.adjType = "vis-activity";
22855                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
22856                    }
22857                    if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
22858                        schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22859                    }
22860                    app.cached = false;
22861                    app.empty = false;
22862                    foregroundActivities = true;
22863                    final TaskRecord task = r.getTask();
22864                    if (task != null && minLayer > 0) {
22865                        final int layer = task.mLayerRank;
22866                        if (layer >= 0 && minLayer > layer) {
22867                            minLayer = layer;
22868                        }
22869                    }
22870                    break;
22871                } else if (r.isState(ActivityState.PAUSING, ActivityState.PAUSED)) {
22872                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22873                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22874                        app.adjType = "pause-activity";
22875                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
22876                    }
22877                    if (procState > PROCESS_STATE_CUR_TOP) {
22878                        procState = PROCESS_STATE_CUR_TOP;
22879                        app.adjType = "pause-activity";
22880                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
22881                    }
22882                    if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
22883                        schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22884                    }
22885                    app.cached = false;
22886                    app.empty = false;
22887                    foregroundActivities = true;
22888                } else if (r.isState(ActivityState.STOPPING)) {
22889                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22890                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22891                        app.adjType = "stop-activity";
22892                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
22893                    }
22894                    // For the process state, we will at this point consider the
22895                    // process to be cached.  It will be cached either as an activity
22896                    // or empty depending on whether the activity is finishing.  We do
22897                    // this so that we can treat the process as cached for purposes of
22898                    // memory trimming (determing current memory level, trim command to
22899                    // send to process) since there can be an arbitrary number of stopping
22900                    // processes and they should soon all go into the cached state.
22901                    if (!r.finishing) {
22902                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
22903                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
22904                            app.adjType = "stop-activity";
22905                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
22906                        }
22907                    }
22908                    app.cached = false;
22909                    app.empty = false;
22910                    foregroundActivities = true;
22911                } else {
22912                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22913                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
22914                        app.adjType = "cch-act";
22915                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
22916                    }
22917                }
22918            }
22919            if (adj == ProcessList.VISIBLE_APP_ADJ) {
22920                adj += minLayer;
22921            }
22922        }
22923        if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) {
22924            procState = ActivityManager.PROCESS_STATE_CACHED_RECENT;
22925            app.adjType = "cch-rec";
22926            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached recent: " + app);
22927        }
22928
22929        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
22930                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
22931            if (app.foregroundServices) {
22932                // The user is aware of this app, so make it visible.
22933                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22934                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
22935                app.cached = false;
22936                app.adjType = "fg-service";
22937                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22938                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
22939            } else if (app.hasOverlayUi) {
22940                // The process is display an overlay UI.
22941                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22942                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22943                app.cached = false;
22944                app.adjType = "has-overlay-ui";
22945                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22946                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
22947            }
22948        }
22949
22950        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
22951                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22952            if (app.forcingToImportant != null) {
22953                // This is currently used for toasts...  they are not interactive, and
22954                // we don't want them to cause the app to become fully foreground (and
22955                // thus out of background check), so we yes the best background level we can.
22956                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22957                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22958                app.cached = false;
22959                app.adjType = "force-imp";
22960                app.adjSource = app.forcingToImportant;
22961                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22962                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
22963            }
22964        }
22965
22966        if (app == mHeavyWeightProcess) {
22967            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
22968                // We don't want to kill the current heavy-weight process.
22969                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
22970                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22971                app.cached = false;
22972                app.adjType = "heavy";
22973                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
22974            }
22975            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22976                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
22977                app.adjType = "heavy";
22978                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
22979            }
22980        }
22981
22982        if (app == mHomeProcess) {
22983            if (adj > ProcessList.HOME_APP_ADJ) {
22984                // This process is hosting what we currently consider to be the
22985                // home app, so we don't want to let it go into the background.
22986                adj = ProcessList.HOME_APP_ADJ;
22987                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22988                app.cached = false;
22989                app.adjType = "home";
22990                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
22991            }
22992            if (procState > ActivityManager.PROCESS_STATE_HOME) {
22993                procState = ActivityManager.PROCESS_STATE_HOME;
22994                app.adjType = "home";
22995                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
22996            }
22997        }
22998
22999        if (app == mPreviousProcess && app.activities.size() > 0) {
23000            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23001                // This was the previous process that showed UI to the user.
23002                // We want to try to keep it around more aggressively, to give
23003                // a good experience around switching between two apps.
23004                adj = ProcessList.PREVIOUS_APP_ADJ;
23005                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23006                app.cached = false;
23007                app.adjType = "previous";
23008                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
23009            }
23010            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23011                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23012                app.adjType = "previous";
23013                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
23014            }
23015        }
23016
23017        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
23018                + " reason=" + app.adjType);
23019
23020        // By default, we use the computed adjustment.  It may be changed if
23021        // there are applications dependent on our services or providers, but
23022        // this gives us a baseline and makes sure we don't get into an
23023        // infinite recursion.
23024        app.adjSeq = mAdjSeq;
23025        app.curRawAdj = adj;
23026        app.hasStartedServices = false;
23027
23028        if (mBackupTarget != null && app == mBackupTarget.app) {
23029            // If possible we want to avoid killing apps while they're being backed up
23030            if (adj > ProcessList.BACKUP_APP_ADJ) {
23031                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
23032                adj = ProcessList.BACKUP_APP_ADJ;
23033                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23034                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23035                }
23036                app.adjType = "backup";
23037                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
23038                app.cached = false;
23039            }
23040            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
23041                procState = ActivityManager.PROCESS_STATE_BACKUP;
23042                app.adjType = "backup";
23043                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
23044            }
23045        }
23046
23047        boolean mayBeTop = false;
23048        String mayBeTopType = null;
23049        Object mayBeTopSource = null;
23050        Object mayBeTopTarget = null;
23051
23052        for (int is = app.services.size()-1;
23053                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23054                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23055                        || procState > ActivityManager.PROCESS_STATE_TOP);
23056                is--) {
23057            ServiceRecord s = app.services.valueAt(is);
23058            if (s.startRequested) {
23059                app.hasStartedServices = true;
23060                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
23061                    procState = ActivityManager.PROCESS_STATE_SERVICE;
23062                    app.adjType = "started-services";
23063                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
23064                }
23065                if (app.hasShownUi && app != mHomeProcess) {
23066                    // If this process has shown some UI, let it immediately
23067                    // go to the LRU list because it may be pretty heavy with
23068                    // UI stuff.  We'll tag it with a label just to help
23069                    // debug and understand what is going on.
23070                    if (adj > ProcessList.SERVICE_ADJ) {
23071                        app.adjType = "cch-started-ui-services";
23072                    }
23073                } else {
23074                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23075                        // This service has seen some activity within
23076                        // recent memory, so we will keep its process ahead
23077                        // of the background processes.
23078                        if (adj > ProcessList.SERVICE_ADJ) {
23079                            adj = ProcessList.SERVICE_ADJ;
23080                            app.adjType = "started-services";
23081                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
23082                            app.cached = false;
23083                        }
23084                    }
23085                    // If we have let the service slide into the background
23086                    // state, still have some text describing what it is doing
23087                    // even though the service no longer has an impact.
23088                    if (adj > ProcessList.SERVICE_ADJ) {
23089                        app.adjType = "cch-started-services";
23090                    }
23091                }
23092            }
23093
23094            for (int conni = s.connections.size()-1;
23095                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23096                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23097                            || procState > ActivityManager.PROCESS_STATE_TOP);
23098                    conni--) {
23099                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
23100                for (int i = 0;
23101                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
23102                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23103                                || procState > ActivityManager.PROCESS_STATE_TOP);
23104                        i++) {
23105                    // XXX should compute this based on the max of
23106                    // all connected clients.
23107                    ConnectionRecord cr = clist.get(i);
23108                    if (cr.binding.client == app) {
23109                        // Binding to ourself is not interesting.
23110                        continue;
23111                    }
23112
23113                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
23114                        ProcessRecord client = cr.binding.client;
23115                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
23116                                TOP_APP, doingAll, now);
23117                        int clientProcState = client.curProcState;
23118                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23119                            // If the other app is cached for any reason, for purposes here
23120                            // we are going to consider it empty.  The specific cached state
23121                            // doesn't propagate except under certain conditions.
23122                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23123                        }
23124                        String adjType = null;
23125                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
23126                            // Not doing bind OOM management, so treat
23127                            // this guy more like a started service.
23128                            if (app.hasShownUi && app != mHomeProcess) {
23129                                // If this process has shown some UI, let it immediately
23130                                // go to the LRU list because it may be pretty heavy with
23131                                // UI stuff.  We'll tag it with a label just to help
23132                                // debug and understand what is going on.
23133                                if (adj > clientAdj) {
23134                                    adjType = "cch-bound-ui-services";
23135                                }
23136                                app.cached = false;
23137                                clientAdj = adj;
23138                                clientProcState = procState;
23139                            } else {
23140                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23141                                    // This service has not seen activity within
23142                                    // recent memory, so allow it to drop to the
23143                                    // LRU list if there is no other reason to keep
23144                                    // it around.  We'll also tag it with a label just
23145                                    // to help debug and undertand what is going on.
23146                                    if (adj > clientAdj) {
23147                                        adjType = "cch-bound-services";
23148                                    }
23149                                    clientAdj = adj;
23150                                }
23151                            }
23152                        }
23153                        if (adj > clientAdj) {
23154                            // If this process has recently shown UI, and
23155                            // the process that is binding to it is less
23156                            // important than being visible, then we don't
23157                            // care about the binding as much as we care
23158                            // about letting this process get into the LRU
23159                            // list to be killed and restarted if needed for
23160                            // memory.
23161                            if (app.hasShownUi && app != mHomeProcess
23162                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23163                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
23164                                    adjType = "cch-bound-ui-services";
23165                                }
23166                            } else {
23167                                int newAdj;
23168                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
23169                                        |Context.BIND_IMPORTANT)) != 0) {
23170                                    newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
23171                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
23172                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
23173                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
23174                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23175                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
23176                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
23177                                    newAdj = clientAdj;
23178                                } else {
23179                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
23180                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
23181                                    } else {
23182                                        newAdj = adj;
23183                                    }
23184                                }
23185                                if (!client.cached) {
23186                                    app.cached = false;
23187                                }
23188                                if (adj >  newAdj) {
23189                                    adj = newAdj;
23190                                    adjType = "service";
23191                                }
23192                            }
23193                        }
23194                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
23195                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
23196                            // This will treat important bound services identically to
23197                            // the top app, which may behave differently than generic
23198                            // foreground work.
23199                            if (client.curSchedGroup > schedGroup) {
23200                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23201                                    schedGroup = client.curSchedGroup;
23202                                } else {
23203                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23204                                }
23205                            }
23206                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23207                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23208                                    // Special handling of clients who are in the top state.
23209                                    // We *may* want to consider this process to be in the
23210                                    // top state as well, but only if there is not another
23211                                    // reason for it to be running.  Being on the top is a
23212                                    // special state, meaning you are specifically running
23213                                    // for the current top app.  If the process is already
23214                                    // running in the background for some other reason, it
23215                                    // is more important to continue considering it to be
23216                                    // in the background state.
23217                                    mayBeTop = true;
23218                                    mayBeTopType = "service";
23219                                    mayBeTopSource = cr.binding.client;
23220                                    mayBeTopTarget = s.name;
23221                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23222                                } else {
23223                                    // Special handling for above-top states (persistent
23224                                    // processes).  These should not bring the current process
23225                                    // into the top state, since they are not on top.  Instead
23226                                    // give them the best state after that.
23227                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
23228                                        clientProcState =
23229                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23230                                    } else if (mWakefulness
23231                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
23232                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
23233                                                    != 0) {
23234                                        clientProcState =
23235                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23236                                    } else {
23237                                        clientProcState =
23238                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23239                                    }
23240                                }
23241                            }
23242                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
23243                            if (clientProcState <
23244                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23245                                clientProcState =
23246                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23247                            }
23248                        } else {
23249                            if (clientProcState <
23250                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
23251                                clientProcState =
23252                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
23253                            }
23254                        }
23255                        if (procState > clientProcState) {
23256                            procState = clientProcState;
23257                            if (adjType == null) {
23258                                adjType = "service";
23259                            }
23260                        }
23261                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
23262                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
23263                            app.pendingUiClean = true;
23264                        }
23265                        if (adjType != null) {
23266                            app.adjType = adjType;
23267                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23268                                    .REASON_SERVICE_IN_USE;
23269                            app.adjSource = cr.binding.client;
23270                            app.adjSourceProcState = clientProcState;
23271                            app.adjTarget = s.name;
23272                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
23273                                    + ": " + app + ", due to " + cr.binding.client
23274                                    + " adj=" + adj + " procState=" + procState);
23275                        }
23276                    }
23277                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
23278                        app.treatLikeActivity = true;
23279                    }
23280                    final ActivityRecord a = cr.activity;
23281                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
23282                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && (a.visible
23283                                || a.isState(ActivityState.RESUMED, ActivityState.PAUSING))) {
23284                            adj = ProcessList.FOREGROUND_APP_ADJ;
23285                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
23286                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23287                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
23288                                } else {
23289                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23290                                }
23291                            }
23292                            app.cached = false;
23293                            app.adjType = "service";
23294                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23295                                    .REASON_SERVICE_IN_USE;
23296                            app.adjSource = a;
23297                            app.adjSourceProcState = procState;
23298                            app.adjTarget = s.name;
23299                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
23300                                    + app);
23301                        }
23302                    }
23303                }
23304            }
23305        }
23306
23307        for (int provi = app.pubProviders.size()-1;
23308                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23309                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23310                        || procState > ActivityManager.PROCESS_STATE_TOP);
23311                provi--) {
23312            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
23313            for (int i = cpr.connections.size()-1;
23314                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23315                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23316                            || procState > ActivityManager.PROCESS_STATE_TOP);
23317                    i--) {
23318                ContentProviderConnection conn = cpr.connections.get(i);
23319                ProcessRecord client = conn.client;
23320                if (client == app) {
23321                    // Being our own client is not interesting.
23322                    continue;
23323                }
23324                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
23325                int clientProcState = client.curProcState;
23326                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23327                    // If the other app is cached for any reason, for purposes here
23328                    // we are going to consider it empty.
23329                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23330                }
23331                String adjType = null;
23332                if (adj > clientAdj) {
23333                    if (app.hasShownUi && app != mHomeProcess
23334                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23335                        adjType = "cch-ui-provider";
23336                    } else {
23337                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
23338                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
23339                        adjType = "provider";
23340                    }
23341                    app.cached &= client.cached;
23342                }
23343                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23344                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23345                        // Special handling of clients who are in the top state.
23346                        // We *may* want to consider this process to be in the
23347                        // top state as well, but only if there is not another
23348                        // reason for it to be running.  Being on the top is a
23349                        // special state, meaning you are specifically running
23350                        // for the current top app.  If the process is already
23351                        // running in the background for some other reason, it
23352                        // is more important to continue considering it to be
23353                        // in the background state.
23354                        mayBeTop = true;
23355                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23356                        mayBeTopType = adjType = "provider-top";
23357                        mayBeTopSource = client;
23358                        mayBeTopTarget = cpr.name;
23359                    } else {
23360                        // Special handling for above-top states (persistent
23361                        // processes).  These should not bring the current process
23362                        // into the top state, since they are not on top.  Instead
23363                        // give them the best state after that.
23364                        clientProcState =
23365                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23366                        if (adjType == null) {
23367                            adjType = "provider";
23368                        }
23369                    }
23370                }
23371                if (procState > clientProcState) {
23372                    procState = clientProcState;
23373                }
23374                if (client.curSchedGroup > schedGroup) {
23375                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23376                }
23377                if (adjType != null) {
23378                    app.adjType = adjType;
23379                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23380                            .REASON_PROVIDER_IN_USE;
23381                    app.adjSource = client;
23382                    app.adjSourceProcState = clientProcState;
23383                    app.adjTarget = cpr.name;
23384                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
23385                            + ": " + app + ", due to " + client
23386                            + " adj=" + adj + " procState=" + procState);
23387                }
23388            }
23389            // If the provider has external (non-framework) process
23390            // dependencies, ensure that its adjustment is at least
23391            // FOREGROUND_APP_ADJ.
23392            if (cpr.hasExternalProcessHandles()) {
23393                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
23394                    adj = ProcessList.FOREGROUND_APP_ADJ;
23395                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23396                    app.cached = false;
23397                    app.adjType = "ext-provider";
23398                    app.adjTarget = cpr.name;
23399                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
23400                }
23401                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23402                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23403                }
23404            }
23405        }
23406
23407        if (app.lastProviderTime > 0 &&
23408                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
23409            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23410                adj = ProcessList.PREVIOUS_APP_ADJ;
23411                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23412                app.cached = false;
23413                app.adjType = "recent-provider";
23414                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
23415            }
23416            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23417                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23418                app.adjType = "recent-provider";
23419                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
23420            }
23421        }
23422
23423        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
23424            // A client of one of our services or providers is in the top state.  We
23425            // *may* want to be in the top state, but not if we are already running in
23426            // the background for some other reason.  For the decision here, we are going
23427            // to pick out a few specific states that we want to remain in when a client
23428            // is top (states that tend to be longer-term) and otherwise allow it to go
23429            // to the top state.
23430            switch (procState) {
23431                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
23432                case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
23433                    // Something else is keeping it at this level, just leave it.
23434                    break;
23435                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
23436                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
23437                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
23438                case ActivityManager.PROCESS_STATE_SERVICE:
23439                    // These all are longer-term states, so pull them up to the top
23440                    // of the background states, but not all the way to the top state.
23441                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23442                    app.adjType = mayBeTopType;
23443                    app.adjSource = mayBeTopSource;
23444                    app.adjTarget = mayBeTopTarget;
23445                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
23446                            + ": " + app + ", due to " + mayBeTopSource
23447                            + " adj=" + adj + " procState=" + procState);
23448                    break;
23449                default:
23450                    // Otherwise, top is a better choice, so take it.
23451                    procState = ActivityManager.PROCESS_STATE_TOP;
23452                    app.adjType = mayBeTopType;
23453                    app.adjSource = mayBeTopSource;
23454                    app.adjTarget = mayBeTopTarget;
23455                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
23456                            + ": " + app + ", due to " + mayBeTopSource
23457                            + " adj=" + adj + " procState=" + procState);
23458                    break;
23459            }
23460        }
23461
23462        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
23463            if (app.hasClientActivities) {
23464                // This is a cached process, but with client activities.  Mark it so.
23465                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
23466                app.adjType = "cch-client-act";
23467            } else if (app.treatLikeActivity) {
23468                // This is a cached process, but somebody wants us to treat it like it has
23469                // an activity, okay!
23470                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
23471                app.adjType = "cch-as-act";
23472            }
23473        }
23474
23475        if (adj == ProcessList.SERVICE_ADJ) {
23476            if (doingAll) {
23477                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
23478                mNewNumServiceProcs++;
23479                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
23480                if (!app.serviceb) {
23481                    // This service isn't far enough down on the LRU list to
23482                    // normally be a B service, but if we are low on RAM and it
23483                    // is large we want to force it down since we would prefer to
23484                    // keep launcher over it.
23485                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
23486                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
23487                        app.serviceHighRam = true;
23488                        app.serviceb = true;
23489                        //Slog.i(TAG, "ADJ " + app + " high ram!");
23490                    } else {
23491                        mNewNumAServiceProcs++;
23492                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
23493                    }
23494                } else {
23495                    app.serviceHighRam = false;
23496                }
23497            }
23498            if (app.serviceb) {
23499                adj = ProcessList.SERVICE_B_ADJ;
23500            }
23501        }
23502
23503        app.curRawAdj = adj;
23504
23505        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
23506        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
23507        if (adj > app.maxAdj) {
23508            adj = app.maxAdj;
23509            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
23510                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23511            }
23512        }
23513
23514        // Do final modification to adj.  Everything we do between here and applying
23515        // the final setAdj must be done in this function, because we will also use
23516        // it when computing the final cached adj later.  Note that we don't need to
23517        // worry about this for max adj above, since max adj will always be used to
23518        // keep it out of the cached vaues.
23519        app.curAdj = app.modifyRawOomAdj(adj);
23520        app.curSchedGroup = schedGroup;
23521        app.curProcState = procState;
23522        app.foregroundActivities = foregroundActivities;
23523
23524        return app.curRawAdj;
23525    }
23526
23527    /**
23528     * Record new PSS sample for a process.
23529     */
23530    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
23531            long rss, int statType, long pssDuration, long now) {
23532        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
23533                swapPss * 1024, rss * 1024, statType, procState, pssDuration);
23534        proc.lastPssTime = now;
23535        proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList);
23536        if (DEBUG_PSS) Slog.d(TAG_PSS,
23537                "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
23538                + " state=" + ProcessList.makeProcStateString(procState));
23539        if (proc.initialIdlePss == 0) {
23540            proc.initialIdlePss = pss;
23541        }
23542        proc.lastPss = pss;
23543        proc.lastSwapPss = swapPss;
23544        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
23545            proc.lastCachedPss = pss;
23546            proc.lastCachedSwapPss = swapPss;
23547        }
23548
23549        final SparseArray<Pair<Long, String>> watchUids
23550                = mMemWatchProcesses.getMap().get(proc.processName);
23551        Long check = null;
23552        if (watchUids != null) {
23553            Pair<Long, String> val = watchUids.get(proc.uid);
23554            if (val == null) {
23555                val = watchUids.get(0);
23556            }
23557            if (val != null) {
23558                check = val.first;
23559            }
23560        }
23561        if (check != null) {
23562            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
23563                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23564                if (!isDebuggable) {
23565                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
23566                        isDebuggable = true;
23567                    }
23568                }
23569                if (isDebuggable) {
23570                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
23571                    final ProcessRecord myProc = proc;
23572                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
23573                    mMemWatchDumpProcName = proc.processName;
23574                    mMemWatchDumpFile = heapdumpFile.toString();
23575                    mMemWatchDumpPid = proc.pid;
23576                    mMemWatchDumpUid = proc.uid;
23577                    BackgroundThread.getHandler().post(new Runnable() {
23578                        @Override
23579                        public void run() {
23580                            revokeUriPermission(ActivityThread.currentActivityThread()
23581                                            .getApplicationThread(),
23582                                    null, DumpHeapActivity.JAVA_URI,
23583                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
23584                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
23585                                    UserHandle.myUserId());
23586                            ParcelFileDescriptor fd = null;
23587                            try {
23588                                heapdumpFile.delete();
23589                                fd = ParcelFileDescriptor.open(heapdumpFile,
23590                                        ParcelFileDescriptor.MODE_CREATE |
23591                                                ParcelFileDescriptor.MODE_TRUNCATE |
23592                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
23593                                                ParcelFileDescriptor.MODE_APPEND);
23594                                IApplicationThread thread = myProc.thread;
23595                                if (thread != null) {
23596                                    try {
23597                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
23598                                                "Requesting dump heap from "
23599                                                + myProc + " to " + heapdumpFile);
23600                                        thread.dumpHeap(/* managed= */ true,
23601                                                /* mallocInfo= */ false, /* runGc= */ false,
23602                                                heapdumpFile.toString(), fd);
23603                                    } catch (RemoteException e) {
23604                                    }
23605                                }
23606                            } catch (FileNotFoundException e) {
23607                                e.printStackTrace();
23608                            } finally {
23609                                if (fd != null) {
23610                                    try {
23611                                        fd.close();
23612                                    } catch (IOException e) {
23613                                    }
23614                                }
23615                            }
23616                        }
23617                    });
23618                } else {
23619                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
23620                            + ", but debugging not enabled");
23621                }
23622            }
23623        }
23624    }
23625
23626    /**
23627     * Schedule PSS collection of a process.
23628     */
23629    boolean requestPssLocked(ProcessRecord proc, int procState) {
23630        if (mPendingPssProcesses.contains(proc)) {
23631            return false;
23632        }
23633        if (mPendingPssProcesses.size() == 0) {
23634            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
23635        }
23636        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
23637        proc.pssProcState = procState;
23638        proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE;
23639        mPendingPssProcesses.add(proc);
23640        return true;
23641    }
23642
23643    /**
23644     * Schedule PSS collection of all processes.
23645     */
23646    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
23647        if (!always) {
23648            if (now < (mLastFullPssTime +
23649                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
23650                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
23651                return;
23652            }
23653        }
23654        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs!  memLowered=" + memLowered);
23655        mLastFullPssTime = now;
23656        mFullPssPending = true;
23657        for (int i = mPendingPssProcesses.size() - 1; i >= 0; i--) {
23658            ProcessList.abortNextPssTime(mPendingPssProcesses.get(i).procStateMemTracker);;
23659        }
23660        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
23661        mPendingPssProcesses.clear();
23662        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23663            ProcessRecord app = mLruProcesses.get(i);
23664            if (app.thread == null
23665                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
23666                continue;
23667            }
23668            if (memLowered || (always && now >
23669                            app.lastStateTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
23670                    || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
23671                app.pssProcState = app.setProcState;
23672                app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
23673                        : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
23674                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
23675                        app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
23676                mPendingPssProcesses.add(app);
23677            }
23678        }
23679        if (!mBgHandler.hasMessages(COLLECT_PSS_BG_MSG)) {
23680            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
23681        }
23682    }
23683
23684    public void setTestPssMode(boolean enabled) {
23685        synchronized (this) {
23686            mTestPssMode = enabled;
23687            if (enabled) {
23688                // Whenever we enable the mode, we want to take a snapshot all of current
23689                // process mem use.
23690                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
23691            }
23692        }
23693    }
23694
23695    /**
23696     * Ask a given process to GC right now.
23697     */
23698    final void performAppGcLocked(ProcessRecord app) {
23699        try {
23700            app.lastRequestedGc = SystemClock.uptimeMillis();
23701            if (app.thread != null) {
23702                if (app.reportLowMemory) {
23703                    app.reportLowMemory = false;
23704                    app.thread.scheduleLowMemory();
23705                } else {
23706                    app.thread.processInBackground();
23707                }
23708            }
23709        } catch (Exception e) {
23710            // whatever.
23711        }
23712    }
23713
23714    /**
23715     * Returns true if things are idle enough to perform GCs.
23716     */
23717    private final boolean canGcNowLocked() {
23718        boolean processingBroadcasts = false;
23719        for (BroadcastQueue q : mBroadcastQueues) {
23720            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
23721                processingBroadcasts = true;
23722            }
23723        }
23724        return !processingBroadcasts
23725                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
23726    }
23727
23728    /**
23729     * Perform GCs on all processes that are waiting for it, but only
23730     * if things are idle.
23731     */
23732    final void performAppGcsLocked() {
23733        final int N = mProcessesToGc.size();
23734        if (N <= 0) {
23735            return;
23736        }
23737        if (canGcNowLocked()) {
23738            while (mProcessesToGc.size() > 0) {
23739                ProcessRecord proc = mProcessesToGc.remove(0);
23740                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
23741                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
23742                            <= SystemClock.uptimeMillis()) {
23743                        // To avoid spamming the system, we will GC processes one
23744                        // at a time, waiting a few seconds between each.
23745                        performAppGcLocked(proc);
23746                        scheduleAppGcsLocked();
23747                        return;
23748                    } else {
23749                        // It hasn't been long enough since we last GCed this
23750                        // process...  put it in the list to wait for its time.
23751                        addProcessToGcListLocked(proc);
23752                        break;
23753                    }
23754                }
23755            }
23756
23757            scheduleAppGcsLocked();
23758        }
23759    }
23760
23761    /**
23762     * If all looks good, perform GCs on all processes waiting for them.
23763     */
23764    final void performAppGcsIfAppropriateLocked() {
23765        if (canGcNowLocked()) {
23766            performAppGcsLocked();
23767            return;
23768        }
23769        // Still not idle, wait some more.
23770        scheduleAppGcsLocked();
23771    }
23772
23773    /**
23774     * Schedule the execution of all pending app GCs.
23775     */
23776    final void scheduleAppGcsLocked() {
23777        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
23778
23779        if (mProcessesToGc.size() > 0) {
23780            // Schedule a GC for the time to the next process.
23781            ProcessRecord proc = mProcessesToGc.get(0);
23782            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
23783
23784            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
23785            long now = SystemClock.uptimeMillis();
23786            if (when < (now+mConstants.GC_TIMEOUT)) {
23787                when = now + mConstants.GC_TIMEOUT;
23788            }
23789            mHandler.sendMessageAtTime(msg, when);
23790        }
23791    }
23792
23793    /**
23794     * Add a process to the array of processes waiting to be GCed.  Keeps the
23795     * list in sorted order by the last GC time.  The process can't already be
23796     * on the list.
23797     */
23798    final void addProcessToGcListLocked(ProcessRecord proc) {
23799        boolean added = false;
23800        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
23801            if (mProcessesToGc.get(i).lastRequestedGc <
23802                    proc.lastRequestedGc) {
23803                added = true;
23804                mProcessesToGc.add(i+1, proc);
23805                break;
23806            }
23807        }
23808        if (!added) {
23809            mProcessesToGc.add(0, proc);
23810        }
23811    }
23812
23813    /**
23814     * Set up to ask a process to GC itself.  This will either do it
23815     * immediately, or put it on the list of processes to gc the next
23816     * time things are idle.
23817     */
23818    final void scheduleAppGcLocked(ProcessRecord app) {
23819        long now = SystemClock.uptimeMillis();
23820        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
23821            return;
23822        }
23823        if (!mProcessesToGc.contains(app)) {
23824            addProcessToGcListLocked(app);
23825            scheduleAppGcsLocked();
23826        }
23827    }
23828
23829    final void checkExcessivePowerUsageLocked() {
23830        updateCpuStatsNow();
23831
23832        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
23833        boolean doCpuKills = true;
23834        if (mLastPowerCheckUptime == 0) {
23835            doCpuKills = false;
23836        }
23837        final long curUptime = SystemClock.uptimeMillis();
23838        final long uptimeSince = curUptime - mLastPowerCheckUptime;
23839        mLastPowerCheckUptime = curUptime;
23840        int i = mLruProcesses.size();
23841        while (i > 0) {
23842            i--;
23843            ProcessRecord app = mLruProcesses.get(i);
23844            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
23845                if (app.lastCpuTime <= 0) {
23846                    continue;
23847                }
23848                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
23849                if (DEBUG_POWER) {
23850                    StringBuilder sb = new StringBuilder(128);
23851                    sb.append("CPU for ");
23852                    app.toShortString(sb);
23853                    sb.append(": over ");
23854                    TimeUtils.formatDuration(uptimeSince, sb);
23855                    sb.append(" used ");
23856                    TimeUtils.formatDuration(cputimeUsed, sb);
23857                    sb.append(" (");
23858                    sb.append((cputimeUsed*100)/uptimeSince);
23859                    sb.append("%)");
23860                    Slog.i(TAG_POWER, sb.toString());
23861                }
23862                // If the process has used too much CPU over the last duration, the
23863                // user probably doesn't want this, so kill!
23864                if (doCpuKills && uptimeSince > 0) {
23865                    // What is the limit for this process?
23866                    int cpuLimit;
23867                    long checkDur = curUptime - app.whenUnimportant;
23868                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
23869                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
23870                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
23871                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
23872                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
23873                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
23874                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
23875                    } else {
23876                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
23877                    }
23878                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
23879                        synchronized (stats) {
23880                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
23881                                    uptimeSince, cputimeUsed);
23882                        }
23883                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
23884                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
23885                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
23886                    }
23887                }
23888                app.lastCpuTime = app.curCpuTime;
23889            }
23890        }
23891    }
23892
23893    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
23894            long nowElapsed) {
23895        boolean success = true;
23896
23897        if (app.curRawAdj != app.setRawAdj) {
23898            app.setRawAdj = app.curRawAdj;
23899        }
23900
23901        int changes = 0;
23902
23903        if (app.curAdj != app.setAdj) {
23904            ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
23905            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
23906                String msg = "Set " + app.pid + " " + app.processName + " adj "
23907                        + app.curAdj + ": " + app.adjType;
23908                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23909            }
23910            app.setAdj = app.curAdj;
23911            app.verifiedAdj = ProcessList.INVALID_ADJ;
23912        }
23913
23914        if (app.setSchedGroup != app.curSchedGroup) {
23915            int oldSchedGroup = app.setSchedGroup;
23916            app.setSchedGroup = app.curSchedGroup;
23917            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
23918                String msg = "Setting sched group of " + app.processName
23919                        + " to " + app.curSchedGroup;
23920                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23921            }
23922            if (app.waitingToKill != null && app.curReceivers.isEmpty()
23923                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
23924                app.kill(app.waitingToKill, true);
23925                success = false;
23926            } else {
23927                int processGroup;
23928                switch (app.curSchedGroup) {
23929                    case ProcessList.SCHED_GROUP_BACKGROUND:
23930                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
23931                        break;
23932                    case ProcessList.SCHED_GROUP_TOP_APP:
23933                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
23934                        processGroup = THREAD_GROUP_TOP_APP;
23935                        break;
23936                    default:
23937                        processGroup = THREAD_GROUP_DEFAULT;
23938                        break;
23939                }
23940                long oldId = Binder.clearCallingIdentity();
23941                try {
23942                    setProcessGroup(app.pid, processGroup);
23943                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
23944                        // do nothing if we already switched to RT
23945                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
23946                            mVrController.onTopProcChangedLocked(app);
23947                            if (mUseFifoUiScheduling) {
23948                                // Switch UI pipeline for app to SCHED_FIFO
23949                                app.savedPriority = Process.getThreadPriority(app.pid);
23950                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
23951                                if (app.renderThreadTid != 0) {
23952                                    scheduleAsFifoPriority(app.renderThreadTid,
23953                                        /* suppressLogs */true);
23954                                    if (DEBUG_OOM_ADJ) {
23955                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
23956                                            app.renderThreadTid + ") to FIFO");
23957                                    }
23958                                } else {
23959                                    if (DEBUG_OOM_ADJ) {
23960                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
23961                                    }
23962                                }
23963                            } else {
23964                                // Boost priority for top app UI and render threads
23965                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
23966                                if (app.renderThreadTid != 0) {
23967                                    try {
23968                                        setThreadPriority(app.renderThreadTid,
23969                                                TOP_APP_PRIORITY_BOOST);
23970                                    } catch (IllegalArgumentException e) {
23971                                        // thread died, ignore
23972                                    }
23973                                }
23974                            }
23975                        }
23976                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
23977                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
23978                        mVrController.onTopProcChangedLocked(app);
23979                        if (mUseFifoUiScheduling) {
23980                            try {
23981                                // Reset UI pipeline to SCHED_OTHER
23982                                setThreadScheduler(app.pid, SCHED_OTHER, 0);
23983                                setThreadPriority(app.pid, app.savedPriority);
23984                                if (app.renderThreadTid != 0) {
23985                                    setThreadScheduler(app.renderThreadTid,
23986                                        SCHED_OTHER, 0);
23987                                    setThreadPriority(app.renderThreadTid, -4);
23988                                }
23989                            } catch (IllegalArgumentException e) {
23990                                Slog.w(TAG,
23991                                        "Failed to set scheduling policy, thread does not exist:\n"
23992                                                + e);
23993                            } catch (SecurityException e) {
23994                                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
23995                            }
23996                        } else {
23997                            // Reset priority for top app UI and render threads
23998                            setThreadPriority(app.pid, 0);
23999                            if (app.renderThreadTid != 0) {
24000                                setThreadPriority(app.renderThreadTid, 0);
24001                            }
24002                        }
24003                    }
24004                } catch (Exception e) {
24005                    if (false) {
24006                        Slog.w(TAG, "Failed setting process group of " + app.pid
24007                                + " to " + app.curSchedGroup);
24008                        Slog.w(TAG, "at location", e);
24009                    }
24010                } finally {
24011                    Binder.restoreCallingIdentity(oldId);
24012                }
24013            }
24014        }
24015        if (app.repForegroundActivities != app.foregroundActivities) {
24016            app.repForegroundActivities = app.foregroundActivities;
24017            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
24018        }
24019        if (app.repProcState != app.curProcState) {
24020            app.repProcState = app.curProcState;
24021            if (app.thread != null) {
24022                try {
24023                    if (false) {
24024                        //RuntimeException h = new RuntimeException("here");
24025                        Slog.i(TAG, "Sending new process state " + app.repProcState
24026                                + " to " + app /*, h*/);
24027                    }
24028                    app.thread.setProcessState(app.repProcState);
24029                } catch (RemoteException e) {
24030                }
24031            }
24032        }
24033        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
24034                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
24035            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
24036                // Experimental code to more aggressively collect pss while
24037                // running test...  the problem is that this tends to collect
24038                // the data right when a process is transitioning between process
24039                // states, which will tend to give noisy data.
24040                long start = SystemClock.uptimeMillis();
24041                long startTime = SystemClock.currentThreadTimeMillis();
24042                long pss = Debug.getPss(app.pid, mTmpLong, null);
24043                long endTime = SystemClock.currentThreadTimeMillis();
24044                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1],
24045                        mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now);
24046                mPendingPssProcesses.remove(app);
24047                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
24048                        + " to " + app.curProcState + ": "
24049                        + (SystemClock.uptimeMillis()-start) + "ms");
24050            }
24051            app.lastStateTime = now;
24052            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24053                    app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24054            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
24055                    + ProcessList.makeProcStateString(app.setProcState) + " to "
24056                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
24057                    + (app.nextPssTime-now) + ": " + app);
24058        } else {
24059            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
24060                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
24061                    mTestPssMode)))) {
24062                if (requestPssLocked(app, app.setProcState)) {
24063                    app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24064                            app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24065                }
24066            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
24067                    "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
24068        }
24069        if (app.setProcState != app.curProcState) {
24070            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
24071                String msg = "Proc state change of " + app.processName
24072                        + " to " + app.curProcState;
24073                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24074            }
24075            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
24076            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
24077            if (setImportant && !curImportant) {
24078                // This app is no longer something we consider important enough to allow to
24079                // use arbitrary amounts of battery power.  Note
24080                // its current CPU time to later know to kill it if
24081                // it is not behaving well.
24082                app.whenUnimportant = now;
24083                app.lastCpuTime = 0;
24084            }
24085            // Inform UsageStats of important process state change
24086            // Must be called before updating setProcState
24087            maybeUpdateUsageStatsLocked(app, nowElapsed);
24088
24089            app.setProcState = app.curProcState;
24090            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24091                app.notCachedSinceIdle = false;
24092            }
24093            if (!doingAll) {
24094                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
24095            } else {
24096                app.procStateChanged = true;
24097            }
24098        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
24099                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
24100            // For apps that sit around for a long time in the interactive state, we need
24101            // to report this at least once a day so they don't go idle.
24102            maybeUpdateUsageStatsLocked(app, nowElapsed);
24103        }
24104
24105        if (changes != 0) {
24106            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24107                    "Changes in " + app + ": " + changes);
24108            int i = mPendingProcessChanges.size()-1;
24109            ProcessChangeItem item = null;
24110            while (i >= 0) {
24111                item = mPendingProcessChanges.get(i);
24112                if (item.pid == app.pid) {
24113                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24114                            "Re-using existing item: " + item);
24115                    break;
24116                }
24117                i--;
24118            }
24119            if (i < 0) {
24120                // No existing item in pending changes; need a new one.
24121                final int NA = mAvailProcessChanges.size();
24122                if (NA > 0) {
24123                    item = mAvailProcessChanges.remove(NA-1);
24124                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24125                            "Retrieving available item: " + item);
24126                } else {
24127                    item = new ProcessChangeItem();
24128                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24129                            "Allocating new item: " + item);
24130                }
24131                item.changes = 0;
24132                item.pid = app.pid;
24133                item.uid = app.info.uid;
24134                if (mPendingProcessChanges.size() == 0) {
24135                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24136                            "*** Enqueueing dispatch processes changed!");
24137                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
24138                }
24139                mPendingProcessChanges.add(item);
24140            }
24141            item.changes |= changes;
24142            item.foregroundActivities = app.repForegroundActivities;
24143            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24144                    "Item " + Integer.toHexString(System.identityHashCode(item))
24145                    + " " + app.toShortString() + ": changes=" + item.changes
24146                    + " foreground=" + item.foregroundActivities
24147                    + " type=" + app.adjType + " source=" + app.adjSource
24148                    + " target=" + app.adjTarget);
24149        }
24150
24151        return success;
24152    }
24153
24154    private boolean isEphemeralLocked(int uid) {
24155        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
24156        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
24157            return false;
24158        }
24159        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
24160                packages[0]);
24161    }
24162
24163    @VisibleForTesting
24164    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
24165        final UidRecord.ChangeItem pendingChange;
24166        if (uidRec == null || uidRec.pendingChange == null) {
24167            if (mPendingUidChanges.size() == 0) {
24168                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24169                        "*** Enqueueing dispatch uid changed!");
24170                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
24171            }
24172            final int NA = mAvailUidChanges.size();
24173            if (NA > 0) {
24174                pendingChange = mAvailUidChanges.remove(NA-1);
24175                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24176                        "Retrieving available item: " + pendingChange);
24177            } else {
24178                pendingChange = new UidRecord.ChangeItem();
24179                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24180                        "Allocating new item: " + pendingChange);
24181            }
24182            if (uidRec != null) {
24183                uidRec.pendingChange = pendingChange;
24184                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
24185                    // If this uid is going away, and we haven't yet reported it is gone,
24186                    // then do so now.
24187                    change |= UidRecord.CHANGE_IDLE;
24188                }
24189            } else if (uid < 0) {
24190                throw new IllegalArgumentException("No UidRecord or uid");
24191            }
24192            pendingChange.uidRecord = uidRec;
24193            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
24194            mPendingUidChanges.add(pendingChange);
24195        } else {
24196            pendingChange = uidRec.pendingChange;
24197            // If there is no change in idle or active state, then keep whatever was pending.
24198            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
24199                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
24200                        | UidRecord.CHANGE_ACTIVE));
24201            }
24202            // If there is no change in cached or uncached state, then keep whatever was pending.
24203            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
24204                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
24205                        | UidRecord.CHANGE_UNCACHED));
24206            }
24207            // If this is a report of the UID being gone, then we shouldn't keep any previous
24208            // report of it being active or cached.  (That is, a gone uid is never active,
24209            // and never cached.)
24210            if ((change & UidRecord.CHANGE_GONE) != 0) {
24211                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
24212                if (!uidRec.idle) {
24213                    // If this uid is going away, and we haven't yet reported it is gone,
24214                    // then do so now.
24215                    change |= UidRecord.CHANGE_IDLE;
24216                }
24217            }
24218        }
24219        pendingChange.change = change;
24220        pendingChange.processState = uidRec != null
24221                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
24222        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
24223        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
24224        if (uidRec != null) {
24225            uidRec.lastReportedChange = change;
24226            uidRec.updateLastDispatchedProcStateSeq(change);
24227        }
24228
24229        // Directly update the power manager, since we sit on top of it and it is critical
24230        // it be kept in sync (so wake locks will be held as soon as appropriate).
24231        if (mLocalPowerManager != null) {
24232            // TO DO: dispatch cached/uncached changes here, so we don't need to report
24233            // all proc state changes.
24234            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
24235                mLocalPowerManager.uidActive(pendingChange.uid);
24236            }
24237            if ((change & UidRecord.CHANGE_IDLE) != 0) {
24238                mLocalPowerManager.uidIdle(pendingChange.uid);
24239            }
24240            if ((change & UidRecord.CHANGE_GONE) != 0) {
24241                mLocalPowerManager.uidGone(pendingChange.uid);
24242            } else {
24243                mLocalPowerManager.updateUidProcState(pendingChange.uid,
24244                        pendingChange.processState);
24245            }
24246        }
24247    }
24248
24249    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
24250            String authority) {
24251        if (app == null) return;
24252        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
24253            UserState userState = mUserController.getStartedUserState(app.userId);
24254            if (userState == null) return;
24255            final long now = SystemClock.elapsedRealtime();
24256            Long lastReported = userState.mProviderLastReportedFg.get(authority);
24257            if (lastReported == null || lastReported < now - 60 * 1000L) {
24258                if (mSystemReady) {
24259                    // Cannot touch the user stats if not system ready
24260                    mUsageStatsService.reportContentProviderUsage(
24261                            authority, providerPkgName, app.userId);
24262                }
24263                userState.mProviderLastReportedFg.put(authority, now);
24264            }
24265        }
24266    }
24267
24268    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
24269        if (DEBUG_USAGE_STATS) {
24270            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
24271                    + "] state changes: old = " + app.setProcState + ", new = "
24272                    + app.curProcState);
24273        }
24274        if (mUsageStatsService == null) {
24275            return;
24276        }
24277        boolean isInteraction;
24278        // To avoid some abuse patterns, we are going to be careful about what we consider
24279        // to be an app interaction.  Being the top activity doesn't count while the display
24280        // is sleeping, nor do short foreground services.
24281        if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
24282            isInteraction = true;
24283            app.fgInteractionTime = 0;
24284        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
24285            if (app.fgInteractionTime == 0) {
24286                app.fgInteractionTime = nowElapsed;
24287                isInteraction = false;
24288            } else {
24289                isInteraction = nowElapsed > app.fgInteractionTime
24290                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
24291            }
24292        } else {
24293            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
24294            app.fgInteractionTime = 0;
24295        }
24296        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
24297                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
24298            app.interactionEventTime = nowElapsed;
24299            String[] packages = app.getPackageList();
24300            if (packages != null) {
24301                for (int i = 0; i < packages.length; i++) {
24302                    mUsageStatsService.reportEvent(packages[i], app.userId,
24303                            UsageEvents.Event.SYSTEM_INTERACTION);
24304                }
24305            }
24306        }
24307        app.reportedInteraction = isInteraction;
24308        if (!isInteraction) {
24309            app.interactionEventTime = 0;
24310        }
24311    }
24312
24313    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
24314        if (proc.thread != null) {
24315            if (proc.baseProcessTracker != null) {
24316                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
24317            }
24318        }
24319    }
24320
24321    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
24322            ProcessRecord TOP_APP, boolean doingAll, long now) {
24323        if (app.thread == null) {
24324            return false;
24325        }
24326
24327        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
24328
24329        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
24330    }
24331
24332    @GuardedBy("this")
24333    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
24334            boolean oomAdj) {
24335        if (isForeground != proc.foregroundServices) {
24336            proc.foregroundServices = isForeground;
24337            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
24338                    proc.info.uid);
24339            if (isForeground) {
24340                if (curProcs == null) {
24341                    curProcs = new ArrayList<ProcessRecord>();
24342                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
24343                }
24344                if (!curProcs.contains(proc)) {
24345                    curProcs.add(proc);
24346                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
24347                            proc.info.packageName, proc.info.uid);
24348                }
24349            } else {
24350                if (curProcs != null) {
24351                    if (curProcs.remove(proc)) {
24352                        mBatteryStatsService.noteEvent(
24353                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
24354                                proc.info.packageName, proc.info.uid);
24355                        if (curProcs.size() <= 0) {
24356                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
24357                        }
24358                    }
24359                }
24360            }
24361            if (oomAdj) {
24362                updateOomAdjLocked();
24363            }
24364        }
24365    }
24366
24367    private final ActivityRecord resumedAppLocked() {
24368        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
24369        String pkg;
24370        int uid;
24371        if (act != null) {
24372            pkg = act.packageName;
24373            uid = act.info.applicationInfo.uid;
24374        } else {
24375            pkg = null;
24376            uid = -1;
24377        }
24378        // Has the UID or resumed package name changed?
24379        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
24380                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
24381            if (mCurResumedPackage != null) {
24382                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
24383                        mCurResumedPackage, mCurResumedUid);
24384            }
24385            mCurResumedPackage = pkg;
24386            mCurResumedUid = uid;
24387            if (mCurResumedPackage != null) {
24388                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
24389                        mCurResumedPackage, mCurResumedUid);
24390            }
24391        }
24392        return act;
24393    }
24394
24395    /**
24396     * Update OomAdj for a specific process.
24397     * @param app The process to update
24398     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
24399     *                  if necessary, or skip.
24400     * @return whether updateOomAdjLocked(app) was successful.
24401     */
24402    @GuardedBy("this")
24403    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
24404        final ActivityRecord TOP_ACT = resumedAppLocked();
24405        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24406        final boolean wasCached = app.cached;
24407
24408        mAdjSeq++;
24409
24410        // This is the desired cached adjusment we want to tell it to use.
24411        // If our app is currently cached, we know it, and that is it.  Otherwise,
24412        // we don't know it yet, and it needs to now be cached we will then
24413        // need to do a complete oom adj.
24414        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
24415                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
24416        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
24417                SystemClock.uptimeMillis());
24418        if (oomAdjAll
24419                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
24420            // Changed to/from cached state, so apps after it in the LRU
24421            // list may also be changed.
24422            updateOomAdjLocked();
24423        }
24424        return success;
24425    }
24426
24427    @GuardedBy("this")
24428    final void updateOomAdjLocked() {
24429        final ActivityRecord TOP_ACT = resumedAppLocked();
24430        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24431        final long now = SystemClock.uptimeMillis();
24432        final long nowElapsed = SystemClock.elapsedRealtime();
24433        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
24434        final int N = mLruProcesses.size();
24435
24436        if (false) {
24437            RuntimeException e = new RuntimeException();
24438            e.fillInStackTrace();
24439            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
24440        }
24441
24442        // Reset state in all uid records.
24443        for (int i=mActiveUids.size()-1; i>=0; i--) {
24444            final UidRecord uidRec = mActiveUids.valueAt(i);
24445            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24446                    "Starting update of " + uidRec);
24447            uidRec.reset();
24448        }
24449
24450        mStackSupervisor.rankTaskLayersIfNeeded();
24451
24452        mAdjSeq++;
24453        mNewNumServiceProcs = 0;
24454        mNewNumAServiceProcs = 0;
24455
24456        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
24457        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
24458
24459        // Let's determine how many processes we have running vs.
24460        // how many slots we have for background processes; we may want
24461        // to put multiple processes in a slot of there are enough of
24462        // them.
24463        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
24464                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
24465        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
24466        if (numEmptyProcs > cachedProcessLimit) {
24467            // If there are more empty processes than our limit on cached
24468            // processes, then use the cached process limit for the factor.
24469            // This ensures that the really old empty processes get pushed
24470            // down to the bottom, so if we are running low on memory we will
24471            // have a better chance at keeping around more cached processes
24472            // instead of a gazillion empty processes.
24473            numEmptyProcs = cachedProcessLimit;
24474        }
24475        int emptyFactor = numEmptyProcs/numSlots;
24476        if (emptyFactor < 1) emptyFactor = 1;
24477        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
24478        if (cachedFactor < 1) cachedFactor = 1;
24479        int stepCached = 0;
24480        int stepEmpty = 0;
24481        int numCached = 0;
24482        int numEmpty = 0;
24483        int numTrimming = 0;
24484
24485        mNumNonCachedProcs = 0;
24486        mNumCachedHiddenProcs = 0;
24487
24488        // First update the OOM adjustment for each of the
24489        // application processes based on their current state.
24490        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
24491        int nextCachedAdj = curCachedAdj+1;
24492        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
24493        int nextEmptyAdj = curEmptyAdj+2;
24494        for (int i=N-1; i>=0; i--) {
24495            ProcessRecord app = mLruProcesses.get(i);
24496            if (!app.killedByAm && app.thread != null) {
24497                app.procStateChanged = false;
24498                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
24499
24500                // If we haven't yet assigned the final cached adj
24501                // to the process, do that now.
24502                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
24503                    switch (app.curProcState) {
24504                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
24505                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
24506                        case ActivityManager.PROCESS_STATE_CACHED_RECENT:
24507                            // This process is a cached process holding activities...
24508                            // assign it the next cached value for that type, and then
24509                            // step that cached level.
24510                            app.curRawAdj = curCachedAdj;
24511                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
24512                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
24513                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
24514                                    + ")");
24515                            if (curCachedAdj != nextCachedAdj) {
24516                                stepCached++;
24517                                if (stepCached >= cachedFactor) {
24518                                    stepCached = 0;
24519                                    curCachedAdj = nextCachedAdj;
24520                                    nextCachedAdj += 2;
24521                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
24522                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
24523                                    }
24524                                }
24525                            }
24526                            break;
24527                        default:
24528                            // For everything else, assign next empty cached process
24529                            // level and bump that up.  Note that this means that
24530                            // long-running services that have dropped down to the
24531                            // cached level will be treated as empty (since their process
24532                            // state is still as a service), which is what we want.
24533                            app.curRawAdj = curEmptyAdj;
24534                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
24535                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
24536                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
24537                                    + ")");
24538                            if (curEmptyAdj != nextEmptyAdj) {
24539                                stepEmpty++;
24540                                if (stepEmpty >= emptyFactor) {
24541                                    stepEmpty = 0;
24542                                    curEmptyAdj = nextEmptyAdj;
24543                                    nextEmptyAdj += 2;
24544                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
24545                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
24546                                    }
24547                                }
24548                            }
24549                            break;
24550                    }
24551                }
24552
24553                applyOomAdjLocked(app, true, now, nowElapsed);
24554
24555                // Count the number of process types.
24556                switch (app.curProcState) {
24557                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
24558                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
24559                        mNumCachedHiddenProcs++;
24560                        numCached++;
24561                        if (numCached > cachedProcessLimit) {
24562                            app.kill("cached #" + numCached, true);
24563                        }
24564                        break;
24565                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
24566                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
24567                                && app.lastActivityTime < oldTime) {
24568                            app.kill("empty for "
24569                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
24570                                    / 1000) + "s", true);
24571                        } else {
24572                            numEmpty++;
24573                            if (numEmpty > emptyProcessLimit) {
24574                                app.kill("empty #" + numEmpty, true);
24575                            }
24576                        }
24577                        break;
24578                    default:
24579                        mNumNonCachedProcs++;
24580                        break;
24581                }
24582
24583                if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
24584                    // If this is an isolated process, there are no services
24585                    // running in it, and it's not a special process with a
24586                    // custom entry point, then the process is no longer
24587                    // needed.  We agressively kill these because we can by
24588                    // definition not re-use the same process again, and it is
24589                    // good to avoid having whatever code was running in them
24590                    // left sitting around after no longer needed.
24591                    app.kill("isolated not needed", true);
24592                } else {
24593                    // Keeping this process, update its uid.
24594                    final UidRecord uidRec = app.uidRecord;
24595                    if (uidRec != null) {
24596                        uidRec.ephemeral = app.info.isInstantApp();
24597                        if (uidRec.curProcState > app.curProcState) {
24598                            uidRec.curProcState = app.curProcState;
24599                        }
24600                        if (app.foregroundServices) {
24601                            uidRec.foregroundServices = true;
24602                        }
24603                    }
24604                }
24605
24606                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
24607                        && !app.killedByAm) {
24608                    numTrimming++;
24609                }
24610            }
24611        }
24612
24613        incrementProcStateSeqAndNotifyAppsLocked();
24614
24615        mNumServiceProcs = mNewNumServiceProcs;
24616
24617        // Now determine the memory trimming level of background processes.
24618        // Unfortunately we need to start at the back of the list to do this
24619        // properly.  We only do this if the number of background apps we
24620        // are managing to keep around is less than half the maximum we desire;
24621        // if we are keeping a good number around, we'll let them use whatever
24622        // memory they want.
24623        final int numCachedAndEmpty = numCached + numEmpty;
24624        int memFactor;
24625        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
24626                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
24627            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
24628                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
24629            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
24630                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
24631            } else {
24632                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
24633            }
24634        } else {
24635            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
24636        }
24637        // We always allow the memory level to go up (better).  We only allow it to go
24638        // down if we are in a state where that is allowed, *and* the total number of processes
24639        // has gone down since last time.
24640        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
24641                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
24642                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
24643        if (memFactor > mLastMemoryLevel) {
24644            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
24645                memFactor = mLastMemoryLevel;
24646                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
24647            }
24648        }
24649        if (memFactor != mLastMemoryLevel) {
24650            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
24651        }
24652        mLastMemoryLevel = memFactor;
24653        mLastNumProcesses = mLruProcesses.size();
24654        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
24655        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
24656        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
24657            if (mLowRamStartTime == 0) {
24658                mLowRamStartTime = now;
24659            }
24660            int step = 0;
24661            int fgTrimLevel;
24662            switch (memFactor) {
24663                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
24664                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
24665                    break;
24666                case ProcessStats.ADJ_MEM_FACTOR_LOW:
24667                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
24668                    break;
24669                default:
24670                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
24671                    break;
24672            }
24673            int factor = numTrimming/3;
24674            int minFactor = 2;
24675            if (mHomeProcess != null) minFactor++;
24676            if (mPreviousProcess != null) minFactor++;
24677            if (factor < minFactor) factor = minFactor;
24678            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
24679            for (int i=N-1; i>=0; i--) {
24680                ProcessRecord app = mLruProcesses.get(i);
24681                if (allChanged || app.procStateChanged) {
24682                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
24683                    app.procStateChanged = false;
24684                }
24685                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
24686                        && !app.killedByAm) {
24687                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
24688                        try {
24689                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24690                                    "Trimming memory of " + app.processName + " to " + curLevel);
24691                            app.thread.scheduleTrimMemory(curLevel);
24692                        } catch (RemoteException e) {
24693                        }
24694                        if (false) {
24695                            // For now we won't do this; our memory trimming seems
24696                            // to be good enough at this point that destroying
24697                            // activities causes more harm than good.
24698                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
24699                                    && app != mHomeProcess && app != mPreviousProcess) {
24700                                // Need to do this on its own message because the stack may not
24701                                // be in a consistent state at this point.
24702                                // For these apps we will also finish their activities
24703                                // to help them free memory.
24704                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
24705                            }
24706                        }
24707                    }
24708                    app.trimMemoryLevel = curLevel;
24709                    step++;
24710                    if (step >= factor) {
24711                        step = 0;
24712                        switch (curLevel) {
24713                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
24714                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
24715                                break;
24716                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
24717                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
24718                                break;
24719                        }
24720                    }
24721                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
24722                        && !app.killedByAm) {
24723                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
24724                            && app.thread != null) {
24725                        try {
24726                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24727                                    "Trimming memory of heavy-weight " + app.processName
24728                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
24729                            app.thread.scheduleTrimMemory(
24730                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
24731                        } catch (RemoteException e) {
24732                        }
24733                    }
24734                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
24735                } else {
24736                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
24737                            || app.systemNoUi) && app.pendingUiClean) {
24738                        // If this application is now in the background and it
24739                        // had done UI, then give it the special trim level to
24740                        // have it free UI resources.
24741                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
24742                        if (app.trimMemoryLevel < level && app.thread != null) {
24743                            try {
24744                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24745                                        "Trimming memory of bg-ui " + app.processName
24746                                        + " to " + level);
24747                                app.thread.scheduleTrimMemory(level);
24748                            } catch (RemoteException e) {
24749                            }
24750                        }
24751                        app.pendingUiClean = false;
24752                    }
24753                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
24754                        try {
24755                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24756                                    "Trimming memory of fg " + app.processName
24757                                    + " to " + fgTrimLevel);
24758                            app.thread.scheduleTrimMemory(fgTrimLevel);
24759                        } catch (RemoteException e) {
24760                        }
24761                    }
24762                    app.trimMemoryLevel = fgTrimLevel;
24763                }
24764            }
24765        } else {
24766            if (mLowRamStartTime != 0) {
24767                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
24768                mLowRamStartTime = 0;
24769            }
24770            for (int i=N-1; i>=0; i--) {
24771                ProcessRecord app = mLruProcesses.get(i);
24772                if (allChanged || app.procStateChanged) {
24773                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
24774                    app.procStateChanged = false;
24775                }
24776                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
24777                        || app.systemNoUi) && app.pendingUiClean) {
24778                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
24779                            && app.thread != null) {
24780                        try {
24781                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24782                                    "Trimming memory of ui hidden " + app.processName
24783                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
24784                            app.thread.scheduleTrimMemory(
24785                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
24786                        } catch (RemoteException e) {
24787                        }
24788                    }
24789                    app.pendingUiClean = false;
24790                }
24791                app.trimMemoryLevel = 0;
24792            }
24793        }
24794
24795        if (mAlwaysFinishActivities) {
24796            // Need to do this on its own message because the stack may not
24797            // be in a consistent state at this point.
24798            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
24799        }
24800
24801        if (allChanged) {
24802            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
24803        }
24804
24805        ArrayList<UidRecord> becameIdle = null;
24806
24807        // Update from any uid changes.
24808        if (mLocalPowerManager != null) {
24809            mLocalPowerManager.startUidChanges();
24810        }
24811        for (int i=mActiveUids.size()-1; i>=0; i--) {
24812            final UidRecord uidRec = mActiveUids.valueAt(i);
24813            int uidChange = UidRecord.CHANGE_PROCSTATE;
24814            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
24815                    && (uidRec.setProcState != uidRec.curProcState
24816                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
24817                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24818                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
24819                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
24820                        + " to " + uidRec.curWhitelist);
24821                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
24822                        && !uidRec.curWhitelist) {
24823                    // UID is now in the background (and not on the temp whitelist).  Was it
24824                    // previously in the foreground (or on the temp whitelist)?
24825                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
24826                            || uidRec.setWhitelist) {
24827                        uidRec.lastBackgroundTime = nowElapsed;
24828                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
24829                            // Note: the background settle time is in elapsed realtime, while
24830                            // the handler time base is uptime.  All this means is that we may
24831                            // stop background uids later than we had intended, but that only
24832                            // happens because the device was sleeping so we are okay anyway.
24833                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
24834                                    mConstants.BACKGROUND_SETTLE_TIME);
24835                        }
24836                    }
24837                    if (uidRec.idle && !uidRec.setIdle) {
24838                        uidChange = UidRecord.CHANGE_IDLE;
24839                        if (becameIdle == null) {
24840                            becameIdle = new ArrayList<>();
24841                        }
24842                        becameIdle.add(uidRec);
24843                    }
24844                } else {
24845                    if (uidRec.idle) {
24846                        uidChange = UidRecord.CHANGE_ACTIVE;
24847                        EventLogTags.writeAmUidActive(uidRec.uid);
24848                        uidRec.idle = false;
24849                    }
24850                    uidRec.lastBackgroundTime = 0;
24851                }
24852                final boolean wasCached = uidRec.setProcState
24853                        > ActivityManager.PROCESS_STATE_RECEIVER;
24854                final boolean isCached = uidRec.curProcState
24855                        > ActivityManager.PROCESS_STATE_RECEIVER;
24856                if (wasCached != isCached ||
24857                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
24858                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
24859                }
24860                uidRec.setProcState = uidRec.curProcState;
24861                uidRec.setWhitelist = uidRec.curWhitelist;
24862                uidRec.setIdle = uidRec.idle;
24863                enqueueUidChangeLocked(uidRec, -1, uidChange);
24864                noteUidProcessState(uidRec.uid, uidRec.curProcState);
24865                if (uidRec.foregroundServices) {
24866                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
24867                }
24868            }
24869        }
24870        if (mLocalPowerManager != null) {
24871            mLocalPowerManager.finishUidChanges();
24872        }
24873
24874        if (becameIdle != null) {
24875            // If we have any new uids that became idle this time, we need to make sure
24876            // they aren't left with running services.
24877            for (int i = becameIdle.size() - 1; i >= 0; i--) {
24878                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
24879            }
24880        }
24881
24882        if (mProcessStats.shouldWriteNowLocked(now)) {
24883            mHandler.post(new Runnable() {
24884                @Override public void run() {
24885                    synchronized (ActivityManagerService.this) {
24886                        mProcessStats.writeStateAsyncLocked();
24887                    }
24888                }
24889            });
24890        }
24891
24892        if (DEBUG_OOM_ADJ) {
24893            final long duration = SystemClock.uptimeMillis() - now;
24894            if (false) {
24895                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
24896                        new RuntimeException("here").fillInStackTrace());
24897            } else {
24898                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
24899            }
24900        }
24901    }
24902
24903    @Override
24904    public void makePackageIdle(String packageName, int userId) {
24905        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
24906                != PackageManager.PERMISSION_GRANTED) {
24907            String msg = "Permission Denial: makePackageIdle() from pid="
24908                    + Binder.getCallingPid()
24909                    + ", uid=" + Binder.getCallingUid()
24910                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
24911            Slog.w(TAG, msg);
24912            throw new SecurityException(msg);
24913        }
24914        final int callingPid = Binder.getCallingPid();
24915        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
24916                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
24917        long callingId = Binder.clearCallingIdentity();
24918        synchronized(this) {
24919            try {
24920                IPackageManager pm = AppGlobals.getPackageManager();
24921                int pkgUid = -1;
24922                try {
24923                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
24924                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
24925                } catch (RemoteException e) {
24926                }
24927                if (pkgUid == -1) {
24928                    throw new IllegalArgumentException("Unknown package name " + packageName);
24929                }
24930
24931                if (mLocalPowerManager != null) {
24932                    mLocalPowerManager.startUidChanges();
24933                }
24934                final int appId = UserHandle.getAppId(pkgUid);
24935                final int N = mActiveUids.size();
24936                for (int i=N-1; i>=0; i--) {
24937                    final UidRecord uidRec = mActiveUids.valueAt(i);
24938                    final long bgTime = uidRec.lastBackgroundTime;
24939                    if (bgTime > 0 && !uidRec.idle) {
24940                        if (UserHandle.getAppId(uidRec.uid) == appId) {
24941                            if (userId == UserHandle.USER_ALL ||
24942                                    userId == UserHandle.getUserId(uidRec.uid)) {
24943                                EventLogTags.writeAmUidIdle(uidRec.uid);
24944                                uidRec.idle = true;
24945                                uidRec.setIdle = true;
24946                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
24947                                        + " from package " + packageName + " user " + userId);
24948                                doStopUidLocked(uidRec.uid, uidRec);
24949                            }
24950                        }
24951                    }
24952                }
24953            } finally {
24954                if (mLocalPowerManager != null) {
24955                    mLocalPowerManager.finishUidChanges();
24956                }
24957                Binder.restoreCallingIdentity(callingId);
24958            }
24959        }
24960    }
24961
24962    final void idleUids() {
24963        synchronized (this) {
24964            final int N = mActiveUids.size();
24965            if (N <= 0) {
24966                return;
24967            }
24968            final long nowElapsed = SystemClock.elapsedRealtime();
24969            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
24970            long nextTime = 0;
24971            if (mLocalPowerManager != null) {
24972                mLocalPowerManager.startUidChanges();
24973            }
24974            for (int i=N-1; i>=0; i--) {
24975                final UidRecord uidRec = mActiveUids.valueAt(i);
24976                final long bgTime = uidRec.lastBackgroundTime;
24977                if (bgTime > 0 && !uidRec.idle) {
24978                    if (bgTime <= maxBgTime) {
24979                        EventLogTags.writeAmUidIdle(uidRec.uid);
24980                        uidRec.idle = true;
24981                        uidRec.setIdle = true;
24982                        doStopUidLocked(uidRec.uid, uidRec);
24983                    } else {
24984                        if (nextTime == 0 || nextTime > bgTime) {
24985                            nextTime = bgTime;
24986                        }
24987                    }
24988                }
24989            }
24990            if (mLocalPowerManager != null) {
24991                mLocalPowerManager.finishUidChanges();
24992            }
24993            if (nextTime > 0) {
24994                mHandler.removeMessages(IDLE_UIDS_MSG);
24995                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
24996                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
24997            }
24998        }
24999    }
25000
25001    /**
25002     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
25003     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
25004     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
25005     */
25006    @VisibleForTesting
25007    @GuardedBy("this")
25008    void incrementProcStateSeqAndNotifyAppsLocked() {
25009        if (mWaitForNetworkTimeoutMs <= 0) {
25010            return;
25011        }
25012        // Used for identifying which uids need to block for network.
25013        ArrayList<Integer> blockingUids = null;
25014        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
25015            final UidRecord uidRec = mActiveUids.valueAt(i);
25016            // If the network is not restricted for uid, then nothing to do here.
25017            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
25018                continue;
25019            }
25020            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
25021                continue;
25022            }
25023            // If process state is not changed, then there's nothing to do.
25024            if (uidRec.setProcState == uidRec.curProcState) {
25025                continue;
25026            }
25027            final int blockState = getBlockStateForUid(uidRec);
25028            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
25029            // there's nothing the app needs to do in this scenario.
25030            if (blockState == NETWORK_STATE_NO_CHANGE) {
25031                continue;
25032            }
25033            synchronized (uidRec.networkStateLock) {
25034                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
25035                if (blockState == NETWORK_STATE_BLOCK) {
25036                    if (blockingUids == null) {
25037                        blockingUids = new ArrayList<>();
25038                    }
25039                    blockingUids.add(uidRec.uid);
25040                } else {
25041                    if (DEBUG_NETWORK) {
25042                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
25043                                + " threads for uid: " + uidRec);
25044                    }
25045                    if (uidRec.waitingForNetwork) {
25046                        uidRec.networkStateLock.notifyAll();
25047                    }
25048                }
25049            }
25050        }
25051
25052        // There are no uids that need to block, so nothing more to do.
25053        if (blockingUids == null) {
25054            return;
25055        }
25056
25057        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
25058            final ProcessRecord app = mLruProcesses.get(i);
25059            if (!blockingUids.contains(app.uid)) {
25060                continue;
25061            }
25062            if (!app.killedByAm && app.thread != null) {
25063                final UidRecord uidRec = mActiveUids.get(app.uid);
25064                try {
25065                    if (DEBUG_NETWORK) {
25066                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
25067                                + uidRec);
25068                    }
25069                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
25070                } catch (RemoteException ignored) {
25071                }
25072            }
25073        }
25074    }
25075
25076    /**
25077     * Checks if the uid is coming from background to foreground or vice versa and returns
25078     * appropriate block state based on this.
25079     *
25080     * @return blockState based on whether the uid is coming from background to foreground or
25081     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
25082     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
25083     *         {@link #NETWORK_STATE_NO_CHANGE}.
25084     */
25085    @VisibleForTesting
25086    int getBlockStateForUid(UidRecord uidRec) {
25087        // Denotes whether uid's process state is currently allowed network access.
25088        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
25089                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
25090        // Denotes whether uid's process state was previously allowed network access.
25091        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
25092                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
25093
25094        // When the uid is coming to foreground, AMS should inform the app thread that it should
25095        // block for the network rules to get updated before launching an activity.
25096        if (!wasAllowed && isAllowed) {
25097            return NETWORK_STATE_BLOCK;
25098        }
25099        // When the uid is going to background, AMS should inform the app thread that if an
25100        // activity launch is blocked for the network rules to get updated, it should be unblocked.
25101        if (wasAllowed && !isAllowed) {
25102            return NETWORK_STATE_UNBLOCK;
25103        }
25104        return NETWORK_STATE_NO_CHANGE;
25105    }
25106
25107    final void runInBackgroundDisabled(int uid) {
25108        synchronized (this) {
25109            UidRecord uidRec = mActiveUids.get(uid);
25110            if (uidRec != null) {
25111                // This uid is actually running...  should it be considered background now?
25112                if (uidRec.idle) {
25113                    doStopUidLocked(uidRec.uid, uidRec);
25114                }
25115            } else {
25116                // This uid isn't actually running...  still send a report about it being "stopped".
25117                doStopUidLocked(uid, null);
25118            }
25119        }
25120    }
25121
25122    /**
25123     * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
25124     */
25125    void doStopUidForIdleUidsLocked() {
25126        final int size = mActiveUids.size();
25127        for (int i = 0; i < size; i++) {
25128            final int uid = mActiveUids.keyAt(i);
25129            if (UserHandle.isCore(uid)) {
25130                continue;
25131            }
25132            final UidRecord uidRec = mActiveUids.valueAt(i);
25133            if (!uidRec.idle) {
25134                continue;
25135            }
25136            doStopUidLocked(uidRec.uid, uidRec);
25137        }
25138    }
25139
25140    final void doStopUidLocked(int uid, final UidRecord uidRec) {
25141        mServices.stopInBackgroundLocked(uid);
25142        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
25143    }
25144
25145    /**
25146     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25147     */
25148    @GuardedBy("this")
25149    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
25150            long duration, String tag) {
25151        if (DEBUG_WHITELISTS) {
25152            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
25153                    + targetUid + ", " + duration + ")");
25154        }
25155
25156        synchronized (mPidsSelfLocked) {
25157            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
25158            if (pr == null) {
25159                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
25160                        + callerPid);
25161                return;
25162            }
25163            if (!pr.whitelistManager) {
25164                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
25165                        != PackageManager.PERMISSION_GRANTED) {
25166                    if (DEBUG_WHITELISTS) {
25167                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
25168                                + ": pid " + callerPid + " is not allowed");
25169                    }
25170                    return;
25171                }
25172            }
25173        }
25174
25175        tempWhitelistUidLocked(targetUid, duration, tag);
25176    }
25177
25178    /**
25179     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25180     */
25181    @GuardedBy("this")
25182    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
25183        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
25184        setUidTempWhitelistStateLocked(targetUid, true);
25185        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
25186    }
25187
25188    void pushTempWhitelist() {
25189        final int N;
25190        final PendingTempWhitelist[] list;
25191
25192        // First copy out the pending changes...  we need to leave them in the map for now,
25193        // in case someone needs to check what is coming up while we don't have the lock held.
25194        synchronized(this) {
25195            N = mPendingTempWhitelist.size();
25196            list = new PendingTempWhitelist[N];
25197            for (int i = 0; i < N; i++) {
25198                list[i] = mPendingTempWhitelist.valueAt(i);
25199            }
25200        }
25201
25202        // Now safely dispatch changes to device idle controller.
25203        for (int i = 0; i < N; i++) {
25204            PendingTempWhitelist ptw = list[i];
25205            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
25206                    ptw.duration, true, ptw.tag);
25207        }
25208
25209        // And now we can safely remove them from the map.
25210        synchronized(this) {
25211            for (int i = 0; i < N; i++) {
25212                PendingTempWhitelist ptw = list[i];
25213                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
25214                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
25215                    mPendingTempWhitelist.removeAt(index);
25216                }
25217            }
25218        }
25219    }
25220
25221    @GuardedBy("this")
25222    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
25223        boolean changed = false;
25224        for (int i=mActiveUids.size()-1; i>=0; i--) {
25225            final UidRecord uidRec = mActiveUids.valueAt(i);
25226            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
25227                uidRec.curWhitelist = onWhitelist;
25228                changed = true;
25229            }
25230        }
25231        if (changed) {
25232            updateOomAdjLocked();
25233        }
25234    }
25235
25236    @GuardedBy("this")
25237    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
25238        boolean changed = false;
25239        final UidRecord uidRec = mActiveUids.get(uid);
25240        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
25241            uidRec.curWhitelist = onWhitelist;
25242            updateOomAdjLocked();
25243        }
25244    }
25245
25246    final void trimApplications() {
25247        synchronized (this) {
25248            int i;
25249
25250            // First remove any unused application processes whose package
25251            // has been removed.
25252            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
25253                final ProcessRecord app = mRemovedProcesses.get(i);
25254                if (app.activities.size() == 0 && app.recentTasks.size() == 0
25255                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
25256                    Slog.i(
25257                        TAG, "Exiting empty application process "
25258                        + app.toShortString() + " ("
25259                        + (app.thread != null ? app.thread.asBinder() : null)
25260                        + ")\n");
25261                    if (app.pid > 0 && app.pid != MY_PID) {
25262                        app.kill("empty", false);
25263                    } else if (app.thread != null) {
25264                        try {
25265                            app.thread.scheduleExit();
25266                        } catch (Exception e) {
25267                            // Ignore exceptions.
25268                        }
25269                    }
25270                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
25271                    mRemovedProcesses.remove(i);
25272
25273                    if (app.persistent) {
25274                        addAppLocked(app.info, null, false, null /* ABI override */);
25275                    }
25276                }
25277            }
25278
25279            // Now update the oom adj for all processes.
25280            updateOomAdjLocked();
25281        }
25282    }
25283
25284    /** This method sends the specified signal to each of the persistent apps */
25285    public void signalPersistentProcesses(int sig) throws RemoteException {
25286        if (sig != SIGNAL_USR1) {
25287            throw new SecurityException("Only SIGNAL_USR1 is allowed");
25288        }
25289
25290        synchronized (this) {
25291            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
25292                    != PackageManager.PERMISSION_GRANTED) {
25293                throw new SecurityException("Requires permission "
25294                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
25295            }
25296
25297            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
25298                ProcessRecord r = mLruProcesses.get(i);
25299                if (r.thread != null && r.persistent) {
25300                    sendSignal(r.pid, sig);
25301                }
25302            }
25303        }
25304    }
25305
25306    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
25307        if (proc == null || proc == mProfileProc) {
25308            proc = mProfileProc;
25309            profileType = mProfileType;
25310            clearProfilerLocked();
25311        }
25312        if (proc == null) {
25313            return;
25314        }
25315        try {
25316            proc.thread.profilerControl(false, null, profileType);
25317        } catch (RemoteException e) {
25318            throw new IllegalStateException("Process disappeared");
25319        }
25320    }
25321
25322    private void clearProfilerLocked() {
25323        if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
25324            try {
25325                mProfilerInfo.profileFd.close();
25326            } catch (IOException e) {
25327            }
25328        }
25329        mProfileApp = null;
25330        mProfileProc = null;
25331        mProfilerInfo = null;
25332    }
25333
25334    public boolean profileControl(String process, int userId, boolean start,
25335            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
25336
25337        try {
25338            synchronized (this) {
25339                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
25340                // its own permission.
25341                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25342                        != PackageManager.PERMISSION_GRANTED) {
25343                    throw new SecurityException("Requires permission "
25344                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25345                }
25346
25347                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
25348                    throw new IllegalArgumentException("null profile info or fd");
25349                }
25350
25351                ProcessRecord proc = null;
25352                if (process != null) {
25353                    proc = findProcessLocked(process, userId, "profileControl");
25354                }
25355
25356                if (start && (proc == null || proc.thread == null)) {
25357                    throw new IllegalArgumentException("Unknown process: " + process);
25358                }
25359
25360                if (start) {
25361                    stopProfilerLocked(null, 0);
25362                    setProfileApp(proc.info, proc.processName, profilerInfo);
25363                    mProfileProc = proc;
25364                    mProfileType = profileType;
25365                    ParcelFileDescriptor fd = profilerInfo.profileFd;
25366                    try {
25367                        fd = fd.dup();
25368                    } catch (IOException e) {
25369                        fd = null;
25370                    }
25371                    profilerInfo.profileFd = fd;
25372                    proc.thread.profilerControl(start, profilerInfo, profileType);
25373                    fd = null;
25374                    try {
25375                        mProfilerInfo.profileFd.close();
25376                    } catch (IOException e) {
25377                    }
25378                    mProfilerInfo.profileFd = null;
25379
25380                    if (proc.pid == MY_PID) {
25381                        // When profiling the system server itself, avoid closing the file
25382                        // descriptor, as profilerControl will not create a copy.
25383                        // Note: it is also not correct to just set profileFd to null, as the
25384                        //       whole ProfilerInfo instance is passed down!
25385                        profilerInfo = null;
25386                    }
25387                } else {
25388                    stopProfilerLocked(proc, profileType);
25389                    if (profilerInfo != null && profilerInfo.profileFd != null) {
25390                        try {
25391                            profilerInfo.profileFd.close();
25392                        } catch (IOException e) {
25393                        }
25394                    }
25395                }
25396
25397                return true;
25398            }
25399        } catch (RemoteException e) {
25400            throw new IllegalStateException("Process disappeared");
25401        } finally {
25402            if (profilerInfo != null && profilerInfo.profileFd != null) {
25403                try {
25404                    profilerInfo.profileFd.close();
25405                } catch (IOException e) {
25406                }
25407            }
25408        }
25409    }
25410
25411    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
25412        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
25413                userId, true, ALLOW_FULL_ONLY, callName, null);
25414        ProcessRecord proc = null;
25415        try {
25416            int pid = Integer.parseInt(process);
25417            synchronized (mPidsSelfLocked) {
25418                proc = mPidsSelfLocked.get(pid);
25419            }
25420        } catch (NumberFormatException e) {
25421        }
25422
25423        if (proc == null) {
25424            ArrayMap<String, SparseArray<ProcessRecord>> all
25425                    = mProcessNames.getMap();
25426            SparseArray<ProcessRecord> procs = all.get(process);
25427            if (procs != null && procs.size() > 0) {
25428                proc = procs.valueAt(0);
25429                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
25430                    for (int i=1; i<procs.size(); i++) {
25431                        ProcessRecord thisProc = procs.valueAt(i);
25432                        if (thisProc.userId == userId) {
25433                            proc = thisProc;
25434                            break;
25435                        }
25436                    }
25437                }
25438            }
25439        }
25440
25441        return proc;
25442    }
25443
25444    public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
25445            boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
25446
25447        try {
25448            synchronized (this) {
25449                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
25450                // its own permission (same as profileControl).
25451                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25452                        != PackageManager.PERMISSION_GRANTED) {
25453                    throw new SecurityException("Requires permission "
25454                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25455                }
25456
25457                if (fd == null) {
25458                    throw new IllegalArgumentException("null fd");
25459                }
25460
25461                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
25462                if (proc == null || proc.thread == null) {
25463                    throw new IllegalArgumentException("Unknown process: " + process);
25464                }
25465
25466                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25467                if (!isDebuggable) {
25468                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25469                        throw new SecurityException("Process not debuggable: " + proc);
25470                    }
25471                }
25472
25473                proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
25474                fd = null;
25475                return true;
25476            }
25477        } catch (RemoteException e) {
25478            throw new IllegalStateException("Process disappeared");
25479        } finally {
25480            if (fd != null) {
25481                try {
25482                    fd.close();
25483                } catch (IOException e) {
25484                }
25485            }
25486        }
25487    }
25488
25489    @Override
25490    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
25491            String reportPackage) {
25492        if (processName != null) {
25493            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
25494                    "setDumpHeapDebugLimit()");
25495        } else {
25496            synchronized (mPidsSelfLocked) {
25497                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
25498                if (proc == null) {
25499                    throw new SecurityException("No process found for calling pid "
25500                            + Binder.getCallingPid());
25501                }
25502                if (!Build.IS_DEBUGGABLE
25503                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25504                    throw new SecurityException("Not running a debuggable build");
25505                }
25506                processName = proc.processName;
25507                uid = proc.uid;
25508                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
25509                    throw new SecurityException("Package " + reportPackage + " is not running in "
25510                            + proc);
25511                }
25512            }
25513        }
25514        synchronized (this) {
25515            if (maxMemSize > 0) {
25516                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
25517            } else {
25518                if (uid != 0) {
25519                    mMemWatchProcesses.remove(processName, uid);
25520                } else {
25521                    mMemWatchProcesses.getMap().remove(processName);
25522                }
25523            }
25524        }
25525    }
25526
25527    @Override
25528    public void dumpHeapFinished(String path) {
25529        synchronized (this) {
25530            if (Binder.getCallingPid() != mMemWatchDumpPid) {
25531                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
25532                        + " does not match last pid " + mMemWatchDumpPid);
25533                return;
25534            }
25535            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
25536                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
25537                        + " does not match last path " + mMemWatchDumpFile);
25538                return;
25539            }
25540            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
25541            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
25542
25543            // Forced gc to clean up the remnant hprof fd.
25544            Runtime.getRuntime().gc();
25545        }
25546    }
25547
25548    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
25549    public void monitor() {
25550        synchronized (this) { }
25551    }
25552
25553    void onCoreSettingsChange(Bundle settings) {
25554        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
25555            ProcessRecord processRecord = mLruProcesses.get(i);
25556            try {
25557                if (processRecord.thread != null) {
25558                    processRecord.thread.setCoreSettings(settings);
25559                }
25560            } catch (RemoteException re) {
25561                /* ignore */
25562            }
25563        }
25564    }
25565
25566    // Multi-user methods
25567
25568    /**
25569     * Start user, if its not already running, but don't bring it to foreground.
25570     */
25571    @Override
25572    public boolean startUserInBackground(final int userId) {
25573        return startUserInBackgroundWithListener(userId, null);
25574    }
25575
25576    @Override
25577    public boolean startUserInBackgroundWithListener(final int userId,
25578                @Nullable IProgressListener unlockListener) {
25579        return mUserController.startUser(userId, /* foreground */ false, unlockListener);
25580    }
25581
25582    @Override
25583    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
25584        return mUserController.unlockUser(userId, token, secret, listener);
25585    }
25586
25587    @Override
25588    public boolean switchUser(final int targetUserId) {
25589        return mUserController.switchUser(targetUserId);
25590    }
25591
25592    @Override
25593    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
25594        return mUserController.stopUser(userId, force, callback);
25595    }
25596
25597    @Override
25598    public UserInfo getCurrentUser() {
25599        return mUserController.getCurrentUser();
25600    }
25601
25602    String getStartedUserState(int userId) {
25603        final UserState userState = mUserController.getStartedUserState(userId);
25604        return UserState.stateToString(userState.state);
25605    }
25606
25607    @Override
25608    public boolean isUserRunning(int userId, int flags) {
25609        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
25610                && checkCallingPermission(INTERACT_ACROSS_USERS)
25611                    != PackageManager.PERMISSION_GRANTED) {
25612            String msg = "Permission Denial: isUserRunning() from pid="
25613                    + Binder.getCallingPid()
25614                    + ", uid=" + Binder.getCallingUid()
25615                    + " requires " + INTERACT_ACROSS_USERS;
25616            Slog.w(TAG, msg);
25617            throw new SecurityException(msg);
25618        }
25619        return mUserController.isUserRunning(userId, flags);
25620    }
25621
25622    @Override
25623    public int[] getRunningUserIds() {
25624        if (checkCallingPermission(INTERACT_ACROSS_USERS)
25625                != PackageManager.PERMISSION_GRANTED) {
25626            String msg = "Permission Denial: isUserRunning() from pid="
25627                    + Binder.getCallingPid()
25628                    + ", uid=" + Binder.getCallingUid()
25629                    + " requires " + INTERACT_ACROSS_USERS;
25630            Slog.w(TAG, msg);
25631            throw new SecurityException(msg);
25632        }
25633        return mUserController.getStartedUserArray();
25634    }
25635
25636    @Override
25637    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
25638        mUserController.registerUserSwitchObserver(observer, name);
25639    }
25640
25641    @Override
25642    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
25643        mUserController.unregisterUserSwitchObserver(observer);
25644    }
25645
25646    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
25647        if (info == null) return null;
25648        ApplicationInfo newInfo = new ApplicationInfo(info);
25649        newInfo.initForUser(userId);
25650        return newInfo;
25651    }
25652
25653    public boolean isUserStopped(int userId) {
25654        return mUserController.getStartedUserState(userId) == null;
25655    }
25656
25657    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
25658        if (aInfo == null
25659                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
25660            return aInfo;
25661        }
25662
25663        ActivityInfo info = new ActivityInfo(aInfo);
25664        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
25665        return info;
25666    }
25667
25668    private boolean processSanityChecksLocked(ProcessRecord process) {
25669        if (process == null || process.thread == null) {
25670            return false;
25671        }
25672
25673        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25674        if (!isDebuggable) {
25675            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25676                return false;
25677            }
25678        }
25679
25680        return true;
25681    }
25682
25683    public boolean startBinderTracking() throws RemoteException {
25684        synchronized (this) {
25685            mBinderTransactionTrackingEnabled = true;
25686            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
25687            // permission (same as profileControl).
25688            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25689                    != PackageManager.PERMISSION_GRANTED) {
25690                throw new SecurityException("Requires permission "
25691                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25692            }
25693
25694            for (int i = 0; i < mLruProcesses.size(); i++) {
25695                ProcessRecord process = mLruProcesses.get(i);
25696                if (!processSanityChecksLocked(process)) {
25697                    continue;
25698                }
25699                try {
25700                    process.thread.startBinderTracking();
25701                } catch (RemoteException e) {
25702                    Log.v(TAG, "Process disappared");
25703                }
25704            }
25705            return true;
25706        }
25707    }
25708
25709    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
25710        try {
25711            synchronized (this) {
25712                mBinderTransactionTrackingEnabled = false;
25713                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
25714                // permission (same as profileControl).
25715                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25716                        != PackageManager.PERMISSION_GRANTED) {
25717                    throw new SecurityException("Requires permission "
25718                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25719                }
25720
25721                if (fd == null) {
25722                    throw new IllegalArgumentException("null fd");
25723                }
25724
25725                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
25726                pw.println("Binder transaction traces for all processes.\n");
25727                for (ProcessRecord process : mLruProcesses) {
25728                    if (!processSanityChecksLocked(process)) {
25729                        continue;
25730                    }
25731
25732                    pw.println("Traces for process: " + process.processName);
25733                    pw.flush();
25734                    try {
25735                        TransferPipe tp = new TransferPipe();
25736                        try {
25737                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
25738                            tp.go(fd.getFileDescriptor());
25739                        } finally {
25740                            tp.kill();
25741                        }
25742                    } catch (IOException e) {
25743                        pw.println("Failure while dumping IPC traces from " + process +
25744                                ".  Exception: " + e);
25745                        pw.flush();
25746                    } catch (RemoteException e) {
25747                        pw.println("Got a RemoteException while dumping IPC traces from " +
25748                                process + ".  Exception: " + e);
25749                        pw.flush();
25750                    }
25751                }
25752                fd = null;
25753                return true;
25754            }
25755        } finally {
25756            if (fd != null) {
25757                try {
25758                    fd.close();
25759                } catch (IOException e) {
25760                }
25761            }
25762        }
25763    }
25764
25765    @VisibleForTesting
25766    final class LocalService extends ActivityManagerInternal {
25767        @Override
25768        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
25769                int targetUserId) {
25770            synchronized (ActivityManagerService.this) {
25771                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
25772                        targetPkg, intent, null, targetUserId);
25773            }
25774        }
25775
25776        @Override
25777        public String checkContentProviderAccess(String authority, int userId) {
25778            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
25779        }
25780
25781        @Override
25782        public void onWakefulnessChanged(int wakefulness) {
25783            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
25784        }
25785
25786        @Override
25787        public boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
25788                String processName, String abiOverride, int uid, Runnable crashHandler) {
25789            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
25790                    processName, abiOverride, uid, crashHandler);
25791        }
25792
25793        @Override
25794        public SleepToken acquireSleepToken(String tag, int displayId) {
25795            Preconditions.checkNotNull(tag);
25796            return ActivityManagerService.this.acquireSleepToken(tag, displayId);
25797        }
25798
25799        @Override
25800        public ComponentName getHomeActivityForUser(int userId) {
25801            synchronized (ActivityManagerService.this) {
25802                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
25803                return homeActivity == null ? null : homeActivity.realActivity;
25804            }
25805        }
25806
25807        @Override
25808        public void onUserRemoved(int userId) {
25809            synchronized (ActivityManagerService.this) {
25810                ActivityManagerService.this.onUserStoppedLocked(userId);
25811            }
25812            mBatteryStatsService.onUserRemoved(userId);
25813            mUserController.onUserRemoved(userId);
25814        }
25815
25816        @Override
25817        public void onLocalVoiceInteractionStarted(IBinder activity,
25818                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
25819            synchronized (ActivityManagerService.this) {
25820                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
25821                        voiceSession, voiceInteractor);
25822            }
25823        }
25824
25825        @Override
25826        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
25827            synchronized (ActivityManagerService.this) {
25828                mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
25829                        reasons, timestamp);
25830            }
25831        }
25832
25833        @Override
25834        public void notifyAppTransitionFinished() {
25835            synchronized (ActivityManagerService.this) {
25836                mStackSupervisor.notifyAppTransitionDone();
25837            }
25838        }
25839
25840        @Override
25841        public void notifyAppTransitionCancelled() {
25842            synchronized (ActivityManagerService.this) {
25843                mStackSupervisor.notifyAppTransitionDone();
25844            }
25845        }
25846
25847        @Override
25848        public List<IBinder> getTopVisibleActivities() {
25849            synchronized (ActivityManagerService.this) {
25850                return mStackSupervisor.getTopVisibleActivities();
25851            }
25852        }
25853
25854        @Override
25855        public void notifyDockedStackMinimizedChanged(boolean minimized) {
25856            synchronized (ActivityManagerService.this) {
25857                mStackSupervisor.setDockedStackMinimized(minimized);
25858            }
25859        }
25860
25861        @Override
25862        public void killForegroundAppsForUser(int userHandle) {
25863            synchronized (ActivityManagerService.this) {
25864                final ArrayList<ProcessRecord> procs = new ArrayList<>();
25865                final int NP = mProcessNames.getMap().size();
25866                for (int ip = 0; ip < NP; ip++) {
25867                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
25868                    final int NA = apps.size();
25869                    for (int ia = 0; ia < NA; ia++) {
25870                        final ProcessRecord app = apps.valueAt(ia);
25871                        if (app.persistent) {
25872                            // We don't kill persistent processes.
25873                            continue;
25874                        }
25875                        if (app.removed) {
25876                            procs.add(app);
25877                        } else if (app.userId == userHandle && app.foregroundActivities) {
25878                            app.removed = true;
25879                            procs.add(app);
25880                        }
25881                    }
25882                }
25883
25884                final int N = procs.size();
25885                for (int i = 0; i < N; i++) {
25886                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
25887                }
25888            }
25889        }
25890
25891        @Override
25892        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
25893                long duration) {
25894            if (!(target instanceof PendingIntentRecord)) {
25895                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
25896                return;
25897            }
25898            synchronized (ActivityManagerService.this) {
25899                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
25900            }
25901        }
25902
25903        @Override
25904        public void setDeviceIdleWhitelist(int[] appids) {
25905            synchronized (ActivityManagerService.this) {
25906                mDeviceIdleWhitelist = appids;
25907            }
25908        }
25909
25910        @Override
25911        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
25912            synchronized (ActivityManagerService.this) {
25913                mDeviceIdleTempWhitelist = appids;
25914                setAppIdTempWhitelistStateLocked(changingAppId, adding);
25915            }
25916        }
25917
25918        @Override
25919        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
25920                int userId) {
25921            Preconditions.checkNotNull(values, "Configuration must not be null");
25922            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
25923            synchronized (ActivityManagerService.this) {
25924                updateConfigurationLocked(values, null, false, true, userId,
25925                        false /* deferResume */);
25926            }
25927        }
25928
25929        @Override
25930        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
25931                Bundle bOptions) {
25932            Preconditions.checkNotNull(intents, "intents");
25933            final String[] resolvedTypes = new String[intents.length];
25934
25935            // UID of the package on user userId.
25936            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
25937            // packageUid may not be initialized.
25938            int packageUid = 0;
25939            final long ident = Binder.clearCallingIdentity();
25940
25941            try {
25942                for (int i = 0; i < intents.length; i++) {
25943                    resolvedTypes[i] =
25944                            intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
25945                }
25946
25947                packageUid = AppGlobals.getPackageManager().getPackageUid(
25948                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
25949            } catch (RemoteException e) {
25950                // Shouldn't happen.
25951            } finally {
25952                Binder.restoreCallingIdentity(ident);
25953            }
25954
25955            synchronized (ActivityManagerService.this) {
25956                return mActivityStartController.startActivitiesInPackage(
25957                        packageUid, packageName,
25958                        intents, resolvedTypes, null /* resultTo */,
25959                        SafeActivityOptions.fromBundle(bOptions), userId,
25960                        false /* validateIncomingUser */);
25961            }
25962        }
25963
25964        @Override
25965        public int getUidProcessState(int uid) {
25966            return getUidState(uid);
25967        }
25968
25969        @Override
25970        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
25971            synchronized (ActivityManagerService.this) {
25972
25973                // We might change the visibilities here, so prepare an empty app transition which
25974                // might be overridden later if we actually change visibilities.
25975                final boolean wasTransitionSet =
25976                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
25977                if (!wasTransitionSet) {
25978                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
25979                            false /* alwaysKeepCurrent */);
25980                }
25981                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
25982
25983                // If there was a transition set already we don't want to interfere with it as we
25984                // might be starting it too early.
25985                if (!wasTransitionSet) {
25986                    mWindowManager.executeAppTransition();
25987                }
25988            }
25989            if (callback != null) {
25990                callback.run();
25991            }
25992        }
25993
25994        @Override
25995        public boolean isSystemReady() {
25996            // no need to synchronize(this) just to read & return the value
25997            return mSystemReady;
25998        }
25999
26000        @Override
26001        public void notifyKeyguardTrustedChanged() {
26002            synchronized (ActivityManagerService.this) {
26003                if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
26004                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
26005                }
26006            }
26007        }
26008
26009        /**
26010         * Sets if the given pid has an overlay UI or not.
26011         *
26012         * @param pid The pid we are setting overlay UI for.
26013         * @param hasOverlayUi True if the process has overlay UI.
26014         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
26015         */
26016        @Override
26017        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
26018            synchronized (ActivityManagerService.this) {
26019                final ProcessRecord pr;
26020                synchronized (mPidsSelfLocked) {
26021                    pr = mPidsSelfLocked.get(pid);
26022                    if (pr == null) {
26023                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
26024                        return;
26025                    }
26026                }
26027                if (pr.hasOverlayUi == hasOverlayUi) {
26028                    return;
26029                }
26030                pr.hasOverlayUi = hasOverlayUi;
26031                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
26032                updateOomAdjLocked(pr, true);
26033            }
26034        }
26035
26036        @Override
26037        public void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
26038            ActivityManagerService.this.setRunningRemoteAnimation(pid, runningRemoteAnimation);
26039        }
26040
26041        /**
26042         * Called after the network policy rules are updated by
26043         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
26044         * and {@param procStateSeq}.
26045         */
26046        @Override
26047        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
26048            if (DEBUG_NETWORK) {
26049                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
26050                        + uid + " seq: " + procStateSeq);
26051            }
26052            UidRecord record;
26053            synchronized (ActivityManagerService.this) {
26054                record = mActiveUids.get(uid);
26055                if (record == null) {
26056                    if (DEBUG_NETWORK) {
26057                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
26058                                + " procStateSeq: " + procStateSeq);
26059                    }
26060                    return;
26061                }
26062            }
26063            synchronized (record.networkStateLock) {
26064                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
26065                    if (DEBUG_NETWORK) {
26066                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
26067                                + " been handled for uid: " + uid);
26068                    }
26069                    return;
26070                }
26071                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
26072                if (record.curProcStateSeq > procStateSeq) {
26073                    if (DEBUG_NETWORK) {
26074                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
26075                                + ", curProcstateSeq: " + record.curProcStateSeq
26076                                + ", procStateSeq: " + procStateSeq);
26077                    }
26078                    return;
26079                }
26080                if (record.waitingForNetwork) {
26081                    if (DEBUG_NETWORK) {
26082                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
26083                                + ", procStateSeq: " + procStateSeq);
26084                    }
26085                    record.networkStateLock.notifyAll();
26086                }
26087            }
26088        }
26089
26090        @Override
26091        public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
26092            synchronized (ActivityManagerService.this) {
26093                mActiveVoiceInteractionServiceComponent = component;
26094            }
26095        }
26096
26097        /**
26098         * Called after virtual display Id is updated by
26099         * {@link com.android.server.vr.Vr2dDisplay} with a specific
26100         * {@param vrVr2dDisplayId}.
26101         */
26102        @Override
26103        public void setVr2dDisplayId(int vr2dDisplayId) {
26104            if (DEBUG_STACK) {
26105                Slog.d(TAG, "setVr2dDisplayId called for: " +
26106                        vr2dDisplayId);
26107            }
26108            synchronized (ActivityManagerService.this) {
26109                mVr2dDisplayId = vr2dDisplayId;
26110            }
26111        }
26112
26113        @Override
26114        public void saveANRState(String reason) {
26115            synchronized (ActivityManagerService.this) {
26116                final StringWriter sw = new StringWriter();
26117                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
26118                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
26119                if (reason != null) {
26120                    pw.println("  Reason: " + reason);
26121                }
26122                pw.println();
26123                mActivityStartController.dump(pw, "  ", null);
26124                pw.println();
26125                pw.println("-------------------------------------------------------------------------------");
26126                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
26127                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
26128                        "" /* header */);
26129                pw.println();
26130                pw.close();
26131
26132                mLastANRState = sw.toString();
26133            }
26134        }
26135
26136        @Override
26137        public void clearSavedANRState() {
26138            synchronized (ActivityManagerService.this) {
26139                mLastANRState = null;
26140            }
26141        }
26142
26143        @Override
26144        public void setFocusedActivity(IBinder token) {
26145            synchronized (ActivityManagerService.this) {
26146                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
26147                if (r == null) {
26148                    throw new IllegalArgumentException(
26149                            "setFocusedActivity: No activity record matching token=" + token);
26150                }
26151                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
26152                        r, "setFocusedActivity")) {
26153                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
26154                }
26155            }
26156        }
26157
26158        @Override
26159        public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
26160            synchronized (ActivityManagerService.this) {
26161                if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
26162                    ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
26163                    if (types == null) {
26164                        if (uid < 0) {
26165                            return;
26166                        }
26167                        types = new ArrayMap<>();
26168                        mAllowAppSwitchUids.put(userId, types);
26169                    }
26170                    if (uid < 0) {
26171                        types.remove(type);
26172                    } else {
26173                        types.put(type, uid);
26174                    }
26175                }
26176            }
26177        }
26178
26179        @Override
26180        public boolean isRuntimeRestarted() {
26181            return mSystemServiceManager.isRuntimeRestarted();
26182        }
26183
26184        @Override
26185        public boolean hasRunningActivity(int uid, @Nullable String packageName) {
26186            if (packageName == null) return false;
26187
26188            synchronized (ActivityManagerService.this) {
26189                for (int i = 0; i < mLruProcesses.size(); i++) {
26190                    final ProcessRecord processRecord = mLruProcesses.get(i);
26191                    if (processRecord.uid == uid) {
26192                        for (int j = 0; j < processRecord.activities.size(); j++) {
26193                            final ActivityRecord activityRecord = processRecord.activities.get(j);
26194                            if (packageName.equals(activityRecord.packageName)) {
26195                                return true;
26196                            }
26197                        }
26198                    }
26199                }
26200            }
26201            return false;
26202        }
26203
26204        @Override
26205        public void registerScreenObserver(ScreenObserver observer) {
26206            mScreenObservers.add(observer);
26207        }
26208
26209        @Override
26210        public boolean canStartMoreUsers() {
26211            return mUserController.canStartMoreUsers();
26212        }
26213
26214        @Override
26215        public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
26216            mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage);
26217        }
26218
26219        @Override
26220        public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
26221            mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage);
26222        }
26223
26224        @Override
26225        public int getMaxRunningUsers() {
26226            return mUserController.mMaxRunningUsers;
26227        }
26228
26229        public boolean isCallerRecents(int callingUid) {
26230            return getRecentTasks().isCallerRecents(callingUid);
26231        }
26232
26233        public boolean isRecentsComponentHomeActivity(int userId) {
26234            return getRecentTasks().isRecentsComponentHomeActivity(userId);
26235        }
26236
26237        @Override
26238        public boolean isUidActive(int uid) {
26239            synchronized (ActivityManagerService.this) {
26240                final UidRecord uidRec = mActiveUids.get(uid);
26241                return (uidRec != null) && !uidRec.idle;
26242            }
26243        }
26244
26245        @Override
26246        public List<ProcessMemoryState> getMemoryStateForProcesses() {
26247            List<ProcessMemoryState> processMemoryStates = new ArrayList<>();
26248            synchronized (mPidsSelfLocked) {
26249                for (int i = 0, size = mPidsSelfLocked.size(); i < size; i++) {
26250                    final ProcessRecord r = mPidsSelfLocked.valueAt(i);
26251                    final int pid = r.pid;
26252                    final int uid = r.uid;
26253                    final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
26254                    if (memoryStat == null) {
26255                        continue;
26256                    }
26257                    ProcessMemoryState processMemoryState =
26258                            new ProcessMemoryState(uid,
26259                                    r.processName,
26260                                    r.maxAdj,
26261                                    memoryStat.pgfault,
26262                                    memoryStat.pgmajfault,
26263                                    memoryStat.rssInBytes,
26264                                    memoryStat.cacheInBytes,
26265                                    memoryStat.swapInBytes);
26266                    processMemoryStates.add(processMemoryState);
26267                }
26268            }
26269            return processMemoryStates;
26270        }
26271    }
26272
26273    /**
26274     * Called by app main thread to wait for the network policy rules to get updated.
26275     *
26276     * @param procStateSeq The sequence number indicating the process state change that the main
26277     *                     thread is interested in.
26278     */
26279    @Override
26280    public void waitForNetworkStateUpdate(long procStateSeq) {
26281        final int callingUid = Binder.getCallingUid();
26282        if (DEBUG_NETWORK) {
26283            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
26284        }
26285        UidRecord record;
26286        synchronized (this) {
26287            record = mActiveUids.get(callingUid);
26288            if (record == null) {
26289                return;
26290            }
26291        }
26292        synchronized (record.networkStateLock) {
26293            if (record.lastDispatchedProcStateSeq < procStateSeq) {
26294                if (DEBUG_NETWORK) {
26295                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
26296                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
26297                            + " lastProcStateSeqDispatchedToObservers: "
26298                            + record.lastDispatchedProcStateSeq);
26299                }
26300                return;
26301            }
26302            if (record.curProcStateSeq > procStateSeq) {
26303                if (DEBUG_NETWORK) {
26304                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
26305                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
26306                            + ", procStateSeq: " + procStateSeq);
26307                }
26308                return;
26309            }
26310            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
26311                if (DEBUG_NETWORK) {
26312                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
26313                            + procStateSeq + ", so no need to wait. Uid: "
26314                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
26315                            + record.lastNetworkUpdatedProcStateSeq);
26316                }
26317                return;
26318            }
26319            try {
26320                if (DEBUG_NETWORK) {
26321                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
26322                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
26323                }
26324                final long startTime = SystemClock.uptimeMillis();
26325                record.waitingForNetwork = true;
26326                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
26327                record.waitingForNetwork = false;
26328                final long totalTime = SystemClock.uptimeMillis() - startTime;
26329                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
26330                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
26331                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
26332                            + procStateSeq + " UidRec: " + record
26333                            + " validateUidRec: " + mValidateUids.get(callingUid));
26334                }
26335            } catch (InterruptedException e) {
26336                Thread.currentThread().interrupt();
26337            }
26338        }
26339    }
26340
26341    public void waitForBroadcastIdle(PrintWriter pw) {
26342        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
26343        while (true) {
26344            boolean idle = true;
26345            synchronized (this) {
26346                for (BroadcastQueue queue : mBroadcastQueues) {
26347                    if (!queue.isIdle()) {
26348                        final String msg = "Waiting for queue " + queue + " to become idle...";
26349                        pw.println(msg);
26350                        pw.flush();
26351                        Slog.v(TAG, msg);
26352                        idle = false;
26353                    }
26354                }
26355            }
26356
26357            if (idle) {
26358                final String msg = "All broadcast queues are idle!";
26359                pw.println(msg);
26360                pw.flush();
26361                Slog.v(TAG, msg);
26362                return;
26363            } else {
26364                SystemClock.sleep(1000);
26365            }
26366        }
26367    }
26368
26369    /**
26370     * Return the user id of the last resumed activity.
26371     */
26372    @Override
26373    public @UserIdInt int getLastResumedActivityUserId() {
26374        enforceCallingPermission(
26375                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
26376        synchronized (this) {
26377            if (mLastResumedActivity == null) {
26378                return mUserController.getCurrentUserId();
26379            }
26380            return mLastResumedActivity.userId;
26381        }
26382    }
26383
26384    /**
26385     * Kill processes for the user with id userId and that depend on the package named packageName
26386     */
26387    @Override
26388    public void killPackageDependents(String packageName, int userId) {
26389        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
26390        if (packageName == null) {
26391            throw new NullPointerException(
26392                    "Cannot kill the dependents of a package without its name.");
26393        }
26394
26395        long callingId = Binder.clearCallingIdentity();
26396        IPackageManager pm = AppGlobals.getPackageManager();
26397        int pkgUid = -1;
26398        try {
26399            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
26400        } catch (RemoteException e) {
26401        }
26402        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
26403            throw new IllegalArgumentException(
26404                    "Cannot kill dependents of non-existing package " + packageName);
26405        }
26406        try {
26407            synchronized(this) {
26408                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
26409                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
26410                        "dep: " + packageName);
26411            }
26412        } finally {
26413            Binder.restoreCallingIdentity(callingId);
26414        }
26415    }
26416
26417    @Override
26418    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
26419            CharSequence message) throws RemoteException {
26420        if (message != null) {
26421            enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
26422                    "dismissKeyguard()");
26423        }
26424        final long callingId = Binder.clearCallingIdentity();
26425        try {
26426            mKeyguardController.dismissKeyguard(token, callback, message);
26427        } finally {
26428            Binder.restoreCallingIdentity(callingId);
26429        }
26430    }
26431
26432    @Override
26433    public int restartUserInBackground(final int userId) {
26434        return mUserController.restartUser(userId, /* foreground */ false);
26435    }
26436
26437    @Override
26438    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
26439        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
26440                "scheduleApplicationInfoChanged()");
26441
26442        synchronized (this) {
26443            final long origId = Binder.clearCallingIdentity();
26444            try {
26445                updateApplicationInfoLocked(packageNames, userId);
26446            } finally {
26447                Binder.restoreCallingIdentity(origId);
26448            }
26449        }
26450    }
26451
26452    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
26453        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
26454        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
26455            final ProcessRecord app = mLruProcesses.get(i);
26456            if (app.thread == null) {
26457                continue;
26458            }
26459
26460            if (userId != UserHandle.USER_ALL && app.userId != userId) {
26461                continue;
26462            }
26463
26464            final int packageCount = app.pkgList.size();
26465            for (int j = 0; j < packageCount; j++) {
26466                final String packageName = app.pkgList.keyAt(j);
26467                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
26468                    try {
26469                        final ApplicationInfo ai = AppGlobals.getPackageManager()
26470                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
26471                        if (ai != null) {
26472                            app.thread.scheduleApplicationInfoChanged(ai);
26473                        }
26474                    } catch (RemoteException e) {
26475                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
26476                                    packageName, app));
26477                    }
26478                }
26479            }
26480        }
26481        if (updateFrameworkRes) {
26482            // Update system server components that need to know about changed overlays. Because the
26483            // overlay is applied in ActivityThread, we need to serialize through its thread too.
26484            final Executor executor = ActivityThread.currentActivityThread().getExecutor();
26485            final DisplayManagerInternal display =
26486                    LocalServices.getService(DisplayManagerInternal.class);
26487            if (display != null) {
26488                executor.execute(display::onOverlayChanged);
26489            }
26490            if (mWindowManager != null) {
26491                executor.execute(mWindowManager::onOverlayChanged);
26492            }
26493        }
26494    }
26495
26496    /**
26497     * Attach an agent to the specified process (proces name or PID)
26498     */
26499    public void attachAgent(String process, String path) {
26500        try {
26501            synchronized (this) {
26502                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
26503                if (proc == null || proc.thread == null) {
26504                    throw new IllegalArgumentException("Unknown process: " + process);
26505                }
26506
26507                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26508                if (!isDebuggable) {
26509                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26510                        throw new SecurityException("Process not debuggable: " + proc);
26511                    }
26512                }
26513
26514                proc.thread.attachAgent(path);
26515            }
26516        } catch (RemoteException e) {
26517            throw new IllegalStateException("Process disappeared");
26518        }
26519    }
26520
26521    @VisibleForTesting
26522    public static class Injector {
26523        private NetworkManagementInternal mNmi;
26524
26525        public Context getContext() {
26526            return null;
26527        }
26528
26529        public AppOpsService getAppOpsService(File file, Handler handler) {
26530            return new AppOpsService(file, handler);
26531        }
26532
26533        public Handler getUiHandler(ActivityManagerService service) {
26534            return service.new UiHandler();
26535        }
26536
26537        public boolean isNetworkRestrictedForUid(int uid) {
26538            if (ensureHasNetworkManagementInternal()) {
26539                return mNmi.isNetworkRestrictedForUid(uid);
26540            }
26541            return false;
26542        }
26543
26544        private boolean ensureHasNetworkManagementInternal() {
26545            if (mNmi == null) {
26546                mNmi = LocalServices.getService(NetworkManagementInternal.class);
26547            }
26548            return mNmi != null;
26549        }
26550    }
26551
26552    @Override
26553    public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
26554            throws RemoteException {
26555        synchronized (this) {
26556            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26557            if (r == null) {
26558                return;
26559            }
26560            final long origId = Binder.clearCallingIdentity();
26561            try {
26562                r.setShowWhenLocked(showWhenLocked);
26563            } finally {
26564                Binder.restoreCallingIdentity(origId);
26565            }
26566        }
26567    }
26568
26569    @Override
26570    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
26571        synchronized (this) {
26572            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26573            if (r == null) {
26574                return;
26575            }
26576            final long origId = Binder.clearCallingIdentity();
26577            try {
26578                r.setTurnScreenOn(turnScreenOn);
26579            } finally {
26580                Binder.restoreCallingIdentity(origId);
26581            }
26582        }
26583    }
26584
26585    @Override
26586    public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)
26587            throws RemoteException {
26588        enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
26589                "registerRemoteAnimations");
26590        definition.setCallingPid(Binder.getCallingPid());
26591        synchronized (this) {
26592            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26593            if (r == null) {
26594                return;
26595            }
26596            final long origId = Binder.clearCallingIdentity();
26597            try {
26598                r.registerRemoteAnimations(definition);
26599            } finally {
26600                Binder.restoreCallingIdentity(origId);
26601            }
26602        }
26603    }
26604
26605    @Override
26606    public void registerRemoteAnimationForNextActivityStart(String packageName,
26607            RemoteAnimationAdapter adapter) throws RemoteException {
26608        enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
26609                "registerRemoteAnimationForNextActivityStart");
26610        adapter.setCallingPid(Binder.getCallingPid());
26611        synchronized (this) {
26612            final long origId = Binder.clearCallingIdentity();
26613            try {
26614                mActivityStartController.registerRemoteAnimationForNextActivityStart(packageName,
26615                        adapter);
26616            } finally {
26617                Binder.restoreCallingIdentity(origId);
26618            }
26619        }
26620    }
26621}
26622