ActivityManagerService.java revision 574aea0f1b073889186a82c94a991cc746b1c58c
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;
125
126import static com.android.internal.util.XmlUtils.readBooleanAttribute;
127import static com.android.internal.util.XmlUtils.readIntAttribute;
128import static com.android.internal.util.XmlUtils.readLongAttribute;
129import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
130import static com.android.internal.util.XmlUtils.writeIntAttribute;
131import static com.android.internal.util.XmlUtils.writeLongAttribute;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
141import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
142import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
143import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
144import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
145import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
146import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
147import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
148import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
149import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
150import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
151import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
152import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
153import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
154import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
155import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
156import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
157import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
158import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
159import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
160import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
161import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
162import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
163import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
164import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
165import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
166import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
167import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
168import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
169import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
170import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
171import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
172import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
173import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
174import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
175import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
176import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
177import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
178import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
179import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
180import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
181import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
182import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
183import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
184import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
185import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
186import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
187import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
188import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
189import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
190import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
191import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
192import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
193import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
194import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
195import static com.android.server.am.MemoryStatUtil.readMemoryStatFromMemcg;
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;
205
206import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
207import static org.xmlpull.v1.XmlPullParser.START_TAG;
208
209import android.Manifest;
210import android.Manifest.permission;
211import android.annotation.NonNull;
212import android.annotation.Nullable;
213import android.annotation.UserIdInt;
214import android.app.Activity;
215import android.app.ActivityManager;
216import android.app.ActivityManager.RunningTaskInfo;
217import android.app.ActivityManager.StackInfo;
218import android.app.ActivityManager.TaskSnapshot;
219import android.app.ActivityManagerInternal;
220import android.app.ActivityManagerInternal.ScreenObserver;
221import android.app.ActivityManagerInternal.SleepToken;
222import android.app.ActivityManagerProto;
223import android.app.ActivityOptions;
224import android.app.ActivityThread;
225import android.app.AlertDialog;
226import android.app.AppGlobals;
227import android.app.AppOpsManager;
228import android.app.ApplicationErrorReport;
229import android.app.ApplicationThreadConstants;
230import android.app.BroadcastOptions;
231import android.app.ContentProviderHolder;
232import android.app.Dialog;
233import android.app.GrantedUriPermission;
234import android.app.IActivityController;
235import android.app.IActivityManager;
236import android.app.IApplicationThread;
237import android.app.IAssistDataReceiver;
238import android.app.IInstrumentationWatcher;
239import android.app.INotificationManager;
240import android.app.IProcessObserver;
241import android.app.IServiceConnection;
242import android.app.IStopUserCallback;
243import android.app.ITaskStackListener;
244import android.app.IUiAutomationConnection;
245import android.app.IUidObserver;
246import android.app.IUserSwitchObserver;
247import android.app.Instrumentation;
248import android.app.Notification;
249import android.app.NotificationManager;
250import android.app.PendingIntent;
251import android.app.PictureInPictureParams;
252import android.app.ProcessMemoryState;
253import android.app.ProfilerInfo;
254import android.app.RemoteAction;
255import android.app.WaitResult;
256import android.app.WindowConfiguration.ActivityType;
257import android.app.WindowConfiguration.WindowingMode;
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;
389
390import android.view.autofill.AutofillManagerInternal;
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.BroadcastProto;
444import com.android.server.am.proto.GrantUriProto;
445import com.android.server.am.proto.ImportanceTokenProto;
446import com.android.server.am.proto.MemInfoProto;
447import com.android.server.am.proto.NeededUriGrantsProto;
448import com.android.server.am.proto.ProcessOomProto;
449import com.android.server.am.proto.ProcessToGcProto;
450import com.android.server.am.proto.ProcessesProto;
451import com.android.server.am.proto.ProcessesProto.UidObserverRegistrationProto;
452import com.android.server.am.proto.StickyBroadcastProto;
453import com.android.server.firewall.IntentFirewall;
454import com.android.server.job.JobSchedulerInternal;
455import com.android.server.pm.Installer;
456import com.android.server.pm.Installer.InstallerException;
457import com.android.server.utils.PriorityDump;
458import com.android.server.vr.VrManagerInternal;
459import com.android.server.wm.PinnedStackWindowController;
460import com.android.server.wm.WindowManagerService;
461
462import dalvik.system.VMRuntime;
463
464import libcore.io.IoUtils;
465import libcore.util.EmptyArray;
466
467import com.google.android.collect.Lists;
468import com.google.android.collect.Maps;
469
470import org.xmlpull.v1.XmlPullParser;
471import org.xmlpull.v1.XmlPullParserException;
472import org.xmlpull.v1.XmlSerializer;
473
474import java.io.File;
475import java.io.FileDescriptor;
476import java.io.FileInputStream;
477import java.io.FileNotFoundException;
478import java.io.FileOutputStream;
479import java.io.IOException;
480import java.io.InputStreamReader;
481import java.io.PrintWriter;
482import java.io.StringWriter;
483import java.io.UnsupportedEncodingException;
484import java.lang.ref.WeakReference;
485import java.nio.charset.StandardCharsets;
486import java.text.DateFormat;
487import java.text.SimpleDateFormat;
488import java.util.ArrayList;
489import java.util.Arrays;
490import java.util.Collections;
491import java.util.Comparator;
492import java.util.Date;
493import java.util.HashMap;
494import java.util.HashSet;
495import java.util.Iterator;
496import java.util.List;
497import java.util.Locale;
498import java.util.Map;
499import java.util.Objects;
500import java.util.Set;
501import java.util.concurrent.CountDownLatch;
502import java.util.concurrent.Executor;
503import java.util.concurrent.atomic.AtomicBoolean;
504import java.util.concurrent.atomic.AtomicLong;
505
506public class ActivityManagerService extends IActivityManager.Stub
507        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
508
509    /**
510     * Priority we boost main thread and RT of top app to.
511     */
512    public static final int TOP_APP_PRIORITY_BOOST = -10;
513
514    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
515    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
516    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
517    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
518    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
519    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
520    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
521    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
522    private static final String TAG_LRU = TAG + POSTFIX_LRU;
523    private static final String TAG_MU = TAG + POSTFIX_MU;
524    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
525    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
526    private static final String TAG_POWER = TAG + POSTFIX_POWER;
527    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
528    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
529    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
530    private static final String TAG_PSS = TAG + POSTFIX_PSS;
531    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
532    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
533    private static final String TAG_STACK = TAG + POSTFIX_STACK;
534    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
535    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
536    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
537    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
538
539    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
540    // here so that while the job scheduler can depend on AMS, the other way around
541    // need not be the case.
542    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
543
544    /** Control over CPU and battery monitoring */
545    // write battery stats every 30 minutes.
546    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
547    static final boolean MONITOR_CPU_USAGE = true;
548    // don't sample cpu less than every 5 seconds.
549    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
550    // wait possibly forever for next cpu sample.
551    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
552    static final boolean MONITOR_THREAD_CPU_USAGE = false;
553
554    // The flags that are set for all calls we make to the package manager.
555    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
556
557    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
558
559    // Amount of time after a call to stopAppSwitches() during which we will
560    // prevent further untrusted switches from happening.
561    static final long APP_SWITCH_DELAY_TIME = 5*1000;
562
563    // How long we wait for a launched process to attach to the activity manager
564    // before we decide it's never going to come up for real.
565    static final int PROC_START_TIMEOUT = 10*1000;
566    // How long we wait for an attached process to publish its content providers
567    // before we decide it must be hung.
568    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
569
570    // How long we wait for a launched process to attach to the activity manager
571    // before we decide it's never going to come up for real, when the process was
572    // started with a wrapper for instrumentation (such as Valgrind) because it
573    // could take much longer than usual.
574    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
575
576    // How long we allow a receiver to run before giving up on it.
577    static final int BROADCAST_FG_TIMEOUT = 10*1000;
578    static final int BROADCAST_BG_TIMEOUT = 60*1000;
579
580    // How long we wait until we timeout on key dispatching.
581    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
582
583    // How long we wait until we timeout on key dispatching during instrumentation.
584    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
585
586    // Disable hidden API checks for the newly started instrumentation.
587    // Must be kept in sync with Am.
588    private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
589
590    // How long to wait in getAssistContextExtras for the activity and foreground services
591    // to respond with the result.
592    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
593
594    // How long top wait when going through the modern assist (which doesn't need to block
595    // on getting this result before starting to launch its UI).
596    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
597
598    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
599    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
600
601    // Maximum number of persisted Uri grants a package is allowed
602    static final int MAX_PERSISTED_URI_GRANTS = 128;
603
604    static final int MY_PID = myPid();
605
606    static final String[] EMPTY_STRING_ARRAY = new String[0];
607
608    // How many bytes to write into the dropbox log before truncating
609    static final int DROPBOX_MAX_SIZE = 192 * 1024;
610    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
611    // as one line, but close enough for now.
612    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
613
614    /** If a UID observer takes more than this long, send a WTF. */
615    private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20;
616
617    // Access modes for handleIncomingUser.
618    static final int ALLOW_NON_FULL = 0;
619    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
620    static final int ALLOW_FULL_ONLY = 2;
621
622    // Necessary ApplicationInfo flags to mark an app as persistent
623    private static final int PERSISTENT_MASK =
624            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
625
626    // Intent sent when remote bugreport collection has been completed
627    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
628            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
629
630    // Used to indicate that an app transition should be animated.
631    static final boolean ANIMATE = true;
632
633    // Determines whether to take full screen screenshots
634    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
635
636    /**
637     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
638     */
639    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
640
641    /**
642     * State indicating that there is no need for any blocking for network.
643     */
644    @VisibleForTesting
645    static final int NETWORK_STATE_NO_CHANGE = 0;
646
647    /**
648     * State indicating that the main thread needs to be informed about the network wait.
649     */
650    @VisibleForTesting
651    static final int NETWORK_STATE_BLOCK = 1;
652
653    /**
654     * State indicating that any threads waiting for network state to get updated can be unblocked.
655     */
656    @VisibleForTesting
657    static final int NETWORK_STATE_UNBLOCK = 2;
658
659    // Max character limit for a notification title. If the notification title is larger than this
660    // the notification will not be legible to the user.
661    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
662
663    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
664
665    /** All system services */
666    SystemServiceManager mSystemServiceManager;
667
668    // Wrapper around VoiceInteractionServiceManager
669    private AssistUtils mAssistUtils;
670
671    // Keeps track of the active voice interaction service component, notified from
672    // VoiceInteractionManagerService
673    ComponentName mActiveVoiceInteractionServiceComponent;
674
675    private Installer mInstaller;
676
677    /** Run all ActivityStacks through this */
678    final ActivityStackSupervisor mStackSupervisor;
679    private final KeyguardController mKeyguardController;
680
681    private final ActivityStartController mActivityStartController;
682
683    final ClientLifecycleManager mLifecycleManager;
684
685    final TaskChangeNotificationController mTaskChangeNotificationController;
686
687    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
688
689    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
690
691    public final IntentFirewall mIntentFirewall;
692
693    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
694    // default action automatically.  Important for devices without direct input
695    // devices.
696    private boolean mShowDialogs = true;
697
698    private final VrController mVrController;
699
700    // VR Vr2d Display Id.
701    int mVr2dDisplayId = INVALID_DISPLAY;
702
703    // Whether we should use SCHED_FIFO for UI and RenderThreads.
704    private boolean mUseFifoUiScheduling = false;
705
706    BroadcastQueue mFgBroadcastQueue;
707    BroadcastQueue mBgBroadcastQueue;
708    // Convenient for easy iteration over the queues. Foreground is first
709    // so that dispatch of foreground broadcasts gets precedence.
710    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
711
712    BroadcastStats mLastBroadcastStats;
713    BroadcastStats mCurBroadcastStats;
714
715    BroadcastQueue broadcastQueueForIntent(Intent intent) {
716        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
717        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
718                "Broadcast intent " + intent + " on "
719                + (isFg ? "foreground" : "background") + " queue");
720        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
721    }
722
723    /**
724     * The last resumed activity. This is identical to the current resumed activity most
725     * of the time but could be different when we're pausing one activity before we resume
726     * another activity.
727     */
728    private ActivityRecord mLastResumedActivity;
729
730    /**
731     * If non-null, we are tracking the time the user spends in the currently focused app.
732     */
733    private AppTimeTracker mCurAppTimeTracker;
734
735    /**
736     * List of intents that were used to start the most recent tasks.
737     */
738    private final RecentTasks mRecentTasks;
739
740    /**
741     * For addAppTask: cached of the last activity component that was added.
742     */
743    ComponentName mLastAddedTaskComponent;
744
745    /**
746     * For addAppTask: cached of the last activity uid that was added.
747     */
748    int mLastAddedTaskUid;
749
750    /**
751     * For addAppTask: cached of the last ActivityInfo that was added.
752     */
753    ActivityInfo mLastAddedTaskActivity;
754
755    /**
756     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
757     */
758    String mDeviceOwnerName;
759
760    /**
761     * The controller for all operations related to locktask.
762     */
763    final LockTaskController mLockTaskController;
764
765    final UserController mUserController;
766
767    /**
768     * Packages that are being allowed to perform unrestricted app switches.  Mapping is
769     * User -> Type -> uid.
770     */
771    final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
772
773    final AppErrors mAppErrors;
774
775    final AppWarnings mAppWarnings;
776
777    /**
778     * Dump of the activity state at the time of the last ANR. Cleared after
779     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
780     */
781    String mLastANRState;
782
783    /**
784     * Indicates the maximum time spent waiting for the network rules to get updated.
785     */
786    @VisibleForTesting
787    long mWaitForNetworkTimeoutMs;
788
789    /** Total # of UID change events dispatched, shown in dumpsys. */
790    int mUidChangeDispatchCount;
791
792    /**
793     * Helper class which strips out priority and proto arguments then calls the dump function with
794     * the appropriate arguments. If priority arguments are omitted, function calls the legacy
795     * dump command.
796     * If priority arguments are omitted all sections are dumped, otherwise sections are dumped
797     * according to their priority.
798     */
799    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
800        @Override
801        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
802                boolean asProto) {
803            if (asProto) return;
804            doDump(fd, pw, new String[]{"activities"}, asProto);
805        }
806
807        @Override
808        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
809            doDump(fd, pw, new String[]{"-a", "--normal-priority"}, asProto);
810        }
811
812        @Override
813        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
814            doDump(fd, pw, args, asProto);
815        }
816    };
817
818    public boolean canShowErrorDialogs() {
819        return mShowDialogs && !mSleeping && !mShuttingDown
820                && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
821                && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
822                        mUserController.getCurrentUserId())
823                && !(UserManager.isDeviceInDemoMode(mContext)
824                        && mUserController.getCurrentUser().isDemo());
825    }
826
827    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
828            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
829
830    static void boostPriorityForLockedSection() {
831        sThreadPriorityBooster.boost();
832    }
833
834    static void resetPriorityAfterLockedSection() {
835        sThreadPriorityBooster.reset();
836    }
837
838    public class PendingAssistExtras extends Binder implements Runnable {
839        public final ActivityRecord activity;
840        public boolean isHome;
841        public final Bundle extras;
842        public final Intent intent;
843        public final String hint;
844        public final IAssistDataReceiver receiver;
845        public final int userHandle;
846        public boolean haveResult = false;
847        public Bundle result = null;
848        public AssistStructure structure = null;
849        public AssistContent content = null;
850        public Bundle receiverExtras;
851
852        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
853                String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
854                int _userHandle) {
855            activity = _activity;
856            extras = _extras;
857            intent = _intent;
858            hint = _hint;
859            receiver = _receiver;
860            receiverExtras = _receiverExtras;
861            userHandle = _userHandle;
862        }
863
864        @Override
865        public void run() {
866            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
867            synchronized (this) {
868                haveResult = true;
869                notifyAll();
870            }
871            pendingAssistExtrasTimedOut(this);
872        }
873    }
874
875    final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
876
877    /**
878     * Process management.
879     */
880    final ProcessList mProcessList = new ProcessList();
881
882    /**
883     * All of the applications we currently have running organized by name.
884     * The keys are strings of the application package name (as
885     * returned by the package manager), and the keys are ApplicationRecord
886     * objects.
887     */
888    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
889
890    /**
891     * Tracking long-term execution of processes to look for abuse and other
892     * bad app behavior.
893     */
894    final ProcessStatsService mProcessStats;
895
896    /**
897     * The currently running isolated processes.
898     */
899    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
900
901    /**
902     * Counter for assigning isolated process uids, to avoid frequently reusing the
903     * same ones.
904     */
905    int mNextIsolatedProcessUid = 0;
906
907    /**
908     * The currently running heavy-weight process, if any.
909     */
910    ProcessRecord mHeavyWeightProcess = null;
911
912    /**
913     * Non-persistent appId whitelist for background restrictions
914     */
915    int[] mBackgroundAppIdWhitelist = new int[] {
916            BLUETOOTH_UID
917    };
918
919    /**
920     * Broadcast actions that will always be deliverable to unlaunched/background apps
921     */
922    ArraySet<String> mBackgroundLaunchBroadcasts;
923
924    /**
925     * All of the processes we currently have running organized by pid.
926     * The keys are the pid running the application.
927     *
928     * <p>NOTE: This object is protected by its own lock, NOT the global
929     * activity manager lock!
930     */
931    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
932
933    /**
934     * All of the processes that have been forced to be important.  The key
935     * is the pid of the caller who requested it (we hold a death
936     * link on it).
937     */
938    abstract class ImportanceToken implements IBinder.DeathRecipient {
939        final int pid;
940        final IBinder token;
941        final String reason;
942
943        ImportanceToken(int _pid, IBinder _token, String _reason) {
944            pid = _pid;
945            token = _token;
946            reason = _reason;
947        }
948
949        @Override
950        public String toString() {
951            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
952                    + " " + reason + " " + pid + " " + token + " }";
953        }
954
955        void writeToProto(ProtoOutputStream proto, long fieldId) {
956            final long pToken = proto.start(fieldId);
957            proto.write(ImportanceTokenProto.PID, pid);
958            if (token != null) {
959                proto.write(ImportanceTokenProto.TOKEN, token.toString());
960            }
961            proto.write(ImportanceTokenProto.REASON, reason);
962            proto.end(pToken);
963        }
964    }
965    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
966
967    /**
968     * List of records for processes that someone had tried to start before the
969     * system was ready.  We don't start them at that point, but ensure they
970     * are started by the time booting is complete.
971     */
972    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
973
974    /**
975     * List of persistent applications that are in the process
976     * of being started.
977     */
978    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
979
980    /**
981     * Processes that are being forcibly torn down.
982     */
983    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
984
985    /**
986     * List of running applications, sorted by recent usage.
987     * The first entry in the list is the least recently used.
988     */
989    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
990
991    /**
992     * Where in mLruProcesses that the processes hosting activities start.
993     */
994    int mLruProcessActivityStart = 0;
995
996    /**
997     * Where in mLruProcesses that the processes hosting services start.
998     * This is after (lower index) than mLruProcessesActivityStart.
999     */
1000    int mLruProcessServiceStart = 0;
1001
1002    /**
1003     * List of processes that should gc as soon as things are idle.
1004     */
1005    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
1006
1007    /**
1008     * Processes we want to collect PSS data from.
1009     */
1010    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
1011
1012    private boolean mBinderTransactionTrackingEnabled = false;
1013
1014    /**
1015     * Last time we requested PSS data of all processes.
1016     */
1017    long mLastFullPssTime = SystemClock.uptimeMillis();
1018
1019    /**
1020     * If set, the next time we collect PSS data we should do a full collection
1021     * with data from native processes and the kernel.
1022     */
1023    boolean mFullPssPending = false;
1024
1025    /**
1026     * This is the process holding what we currently consider to be
1027     * the "home" activity.
1028     */
1029    ProcessRecord mHomeProcess;
1030
1031    /**
1032     * This is the process holding the activity the user last visited that
1033     * is in a different process from the one they are currently in.
1034     */
1035    ProcessRecord mPreviousProcess;
1036
1037    /**
1038     * The time at which the previous process was last visible.
1039     */
1040    long mPreviousProcessVisibleTime;
1041
1042    /**
1043     * Track all uids that have actively running processes.
1044     */
1045    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
1046
1047    /**
1048     * This is for verifying the UID report flow.
1049     */
1050    static final boolean VALIDATE_UID_STATES = true;
1051    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
1052
1053    /**
1054     * Packages that the user has asked to have run in screen size
1055     * compatibility mode instead of filling the screen.
1056     */
1057    final CompatModePackages mCompatModePackages;
1058
1059    /**
1060     * Set of IntentSenderRecord objects that are currently active.
1061     */
1062    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1063            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1064
1065    /**
1066     * Fingerprints (hashCode()) of stack traces that we've
1067     * already logged DropBox entries for.  Guarded by itself.  If
1068     * something (rogue user app) forces this over
1069     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1070     */
1071    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1072    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1073
1074    /**
1075     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1076     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1077     */
1078    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1079
1080    /**
1081     * Resolver for broadcast intents to registered receivers.
1082     * Holds BroadcastFilter (subclass of IntentFilter).
1083     */
1084    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1085            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1086        @Override
1087        protected boolean allowFilterResult(
1088                BroadcastFilter filter, List<BroadcastFilter> dest) {
1089            IBinder target = filter.receiverList.receiver.asBinder();
1090            for (int i = dest.size() - 1; i >= 0; i--) {
1091                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1092                    return false;
1093                }
1094            }
1095            return true;
1096        }
1097
1098        @Override
1099        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1100            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1101                    || userId == filter.owningUserId) {
1102                return super.newResult(filter, match, userId);
1103            }
1104            return null;
1105        }
1106
1107        @Override
1108        protected BroadcastFilter[] newArray(int size) {
1109            return new BroadcastFilter[size];
1110        }
1111
1112        @Override
1113        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1114            return packageName.equals(filter.packageName);
1115        }
1116    };
1117
1118    /**
1119     * State of all active sticky broadcasts per user.  Keys are the action of the
1120     * sticky Intent, values are an ArrayList of all broadcasted intents with
1121     * that action (which should usually be one).  The SparseArray is keyed
1122     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1123     * for stickies that are sent to all users.
1124     */
1125    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1126            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1127
1128    final ActiveServices mServices;
1129
1130    final static class Association {
1131        final int mSourceUid;
1132        final String mSourceProcess;
1133        final int mTargetUid;
1134        final ComponentName mTargetComponent;
1135        final String mTargetProcess;
1136
1137        int mCount;
1138        long mTime;
1139
1140        int mNesting;
1141        long mStartTime;
1142
1143        // states of the source process when the bind occurred.
1144        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1145        long mLastStateUptime;
1146        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1147                - ActivityManager.MIN_PROCESS_STATE+1];
1148
1149        Association(int sourceUid, String sourceProcess, int targetUid,
1150                ComponentName targetComponent, String targetProcess) {
1151            mSourceUid = sourceUid;
1152            mSourceProcess = sourceProcess;
1153            mTargetUid = targetUid;
1154            mTargetComponent = targetComponent;
1155            mTargetProcess = targetProcess;
1156        }
1157    }
1158
1159    /**
1160     * When service association tracking is enabled, this is all of the associations we
1161     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1162     * -> association data.
1163     */
1164    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1165            mAssociations = new SparseArray<>();
1166    boolean mTrackingAssociations;
1167
1168    /**
1169     * Backup/restore process management
1170     */
1171    String mBackupAppName = null;
1172    BackupRecord mBackupTarget = null;
1173
1174    final ProviderMap mProviderMap;
1175
1176    /**
1177     * List of content providers who have clients waiting for them.  The
1178     * application is currently being launched and the provider will be
1179     * removed from this list once it is published.
1180     */
1181    final ArrayList<ContentProviderRecord> mLaunchingProviders
1182            = new ArrayList<ContentProviderRecord>();
1183
1184    /**
1185     * File storing persisted {@link #mGrantedUriPermissions}.
1186     */
1187    private final AtomicFile mGrantFile;
1188
1189    /** XML constants used in {@link #mGrantFile} */
1190    private static final String TAG_URI_GRANTS = "uri-grants";
1191    private static final String TAG_URI_GRANT = "uri-grant";
1192    private static final String ATTR_USER_HANDLE = "userHandle";
1193    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1194    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1195    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1196    private static final String ATTR_TARGET_PKG = "targetPkg";
1197    private static final String ATTR_URI = "uri";
1198    private static final String ATTR_MODE_FLAGS = "modeFlags";
1199    private static final String ATTR_CREATED_TIME = "createdTime";
1200    private static final String ATTR_PREFIX = "prefix";
1201
1202    /**
1203     * Global set of specific {@link Uri} permissions that have been granted.
1204     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1205     * to {@link UriPermission#uri} to {@link UriPermission}.
1206     */
1207    @GuardedBy("this")
1208    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1209            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1210
1211    public static class GrantUri {
1212        public final int sourceUserId;
1213        public final Uri uri;
1214        public boolean prefix;
1215
1216        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1217            this.sourceUserId = sourceUserId;
1218            this.uri = uri;
1219            this.prefix = prefix;
1220        }
1221
1222        @Override
1223        public int hashCode() {
1224            int hashCode = 1;
1225            hashCode = 31 * hashCode + sourceUserId;
1226            hashCode = 31 * hashCode + uri.hashCode();
1227            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1228            return hashCode;
1229        }
1230
1231        @Override
1232        public boolean equals(Object o) {
1233            if (o instanceof GrantUri) {
1234                GrantUri other = (GrantUri) o;
1235                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1236                        && prefix == other.prefix;
1237            }
1238            return false;
1239        }
1240
1241        @Override
1242        public String toString() {
1243            String result = uri.toString() + " [user " + sourceUserId + "]";
1244            if (prefix) result += " [prefix]";
1245            return result;
1246        }
1247
1248        public String toSafeString() {
1249            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1250            if (prefix) result += " [prefix]";
1251            return result;
1252        }
1253
1254        public void writeToProto(ProtoOutputStream proto, long fieldId) {
1255            long token = proto.start(fieldId);
1256            proto.write(GrantUriProto.URI, uri.toString());
1257            proto.write(GrantUriProto.SOURCE_USER_ID, sourceUserId);
1258            proto.end(token);
1259        }
1260
1261        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1262            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1263                    ContentProvider.getUriWithoutUserId(uri), false);
1264        }
1265    }
1266
1267    CoreSettingsObserver mCoreSettingsObserver;
1268
1269    FontScaleSettingObserver mFontScaleSettingObserver;
1270
1271    private final class FontScaleSettingObserver extends ContentObserver {
1272        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1273
1274        public FontScaleSettingObserver() {
1275            super(mHandler);
1276            ContentResolver resolver = mContext.getContentResolver();
1277            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1278        }
1279
1280        @Override
1281        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1282            if (mFontScaleUri.equals(uri)) {
1283                updateFontScaleIfNeeded(userId);
1284            }
1285        }
1286    }
1287
1288    DevelopmentSettingsObserver mDevelopmentSettingsObserver;
1289
1290    private final class DevelopmentSettingsObserver extends ContentObserver {
1291        private final Uri mUri = Settings.Global
1292                .getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
1293
1294        private final ComponentName mBugreportStorageProvider = new ComponentName(
1295                "com.android.shell", "com.android.shell.BugreportStorageProvider");
1296
1297        public DevelopmentSettingsObserver() {
1298            super(mHandler);
1299            mContext.getContentResolver().registerContentObserver(mUri, false, this,
1300                    UserHandle.USER_ALL);
1301            // Always kick once to ensure that we match current state
1302            onChange();
1303        }
1304
1305        @Override
1306        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1307            if (mUri.equals(uri)) {
1308                onChange();
1309            }
1310        }
1311
1312        public void onChange() {
1313            final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
1314                    Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, Build.IS_ENG ? 1 : 0) != 0;
1315            mContext.getPackageManager().setComponentEnabledSetting(mBugreportStorageProvider,
1316                    enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1317                            : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
1318                    0);
1319        }
1320    }
1321
1322    /**
1323     * Thread-local storage used to carry caller permissions over through
1324     * indirect content-provider access.
1325     */
1326    private class Identity {
1327        public final IBinder token;
1328        public final int pid;
1329        public final int uid;
1330
1331        Identity(IBinder _token, int _pid, int _uid) {
1332            token = _token;
1333            pid = _pid;
1334            uid = _uid;
1335        }
1336    }
1337
1338    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1339
1340    /**
1341     * All information we have collected about the runtime performance of
1342     * any user id that can impact battery performance.
1343     */
1344    final BatteryStatsService mBatteryStatsService;
1345
1346    /**
1347     * Information about component usage
1348     */
1349    UsageStatsManagerInternal mUsageStatsService;
1350
1351    /**
1352     * Access to DeviceIdleController service.
1353     */
1354    DeviceIdleController.LocalService mLocalDeviceIdleController;
1355
1356    /**
1357     * Set of app ids that are whitelisted for device idle and thus background check.
1358     */
1359    int[] mDeviceIdleWhitelist = new int[0];
1360
1361    /**
1362     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1363     */
1364    int[] mDeviceIdleTempWhitelist = new int[0];
1365
1366    static final class PendingTempWhitelist {
1367        final int targetUid;
1368        final long duration;
1369        final String tag;
1370
1371        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1372            targetUid = _targetUid;
1373            duration = _duration;
1374            tag = _tag;
1375        }
1376
1377        void writeToProto(ProtoOutputStream proto, long fieldId) {
1378            final long token = proto.start(fieldId);
1379            proto.write(ProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
1380            proto.write(ProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
1381            proto.write(ProcessesProto.PendingTempWhitelist.TAG, tag);
1382            proto.end(token);
1383        }
1384    }
1385
1386    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1387
1388    /**
1389     * Information about and control over application operations
1390     */
1391    final AppOpsService mAppOpsService;
1392
1393    /** Current sequencing integer of the configuration, for skipping old configurations. */
1394    private int mConfigurationSeq;
1395
1396    /**
1397     * Temp object used when global and/or display override configuration is updated. It is also
1398     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1399     * anyone...
1400     */
1401    private Configuration mTempConfig = new Configuration();
1402
1403    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1404            new UpdateConfigurationResult();
1405    private static final class UpdateConfigurationResult {
1406        // Configuration changes that were updated.
1407        int changes;
1408        // If the activity was relaunched to match the new configuration.
1409        boolean activityRelaunched;
1410
1411        void reset() {
1412            changes = 0;
1413            activityRelaunched = false;
1414        }
1415    }
1416
1417    boolean mSuppressResizeConfigChanges;
1418
1419    /**
1420     * Hardware-reported OpenGLES version.
1421     */
1422    final int GL_ES_VERSION;
1423
1424    /**
1425     * List of initialization arguments to pass to all processes when binding applications to them.
1426     * For example, references to the commonly used services.
1427     */
1428    HashMap<String, IBinder> mAppBindArgs;
1429    HashMap<String, IBinder> mIsolatedAppBindArgs;
1430
1431    /**
1432     * Temporary to avoid allocations.  Protected by main lock.
1433     */
1434    final StringBuilder mStringBuilder = new StringBuilder(256);
1435
1436    /**
1437     * Used to control how we initialize the service.
1438     */
1439    ComponentName mTopComponent;
1440    String mTopAction = Intent.ACTION_MAIN;
1441    String mTopData;
1442
1443    volatile boolean mProcessesReady = false;
1444    volatile boolean mSystemReady = false;
1445    volatile boolean mOnBattery = false;
1446    volatile int mFactoryTest;
1447
1448    @GuardedBy("this") boolean mBooting = false;
1449    @GuardedBy("this") boolean mCallFinishBooting = false;
1450    @GuardedBy("this") boolean mBootAnimationComplete = false;
1451    @GuardedBy("this") boolean mLaunchWarningShown = false;
1452    private @GuardedBy("this") boolean mCheckedForSetup = false;
1453
1454    final Context mContext;
1455
1456    /**
1457     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1458     * change at runtime. Use mContext for non-UI purposes.
1459     */
1460    final Context mUiContext;
1461
1462    /**
1463     * The time at which we will allow normal application switches again,
1464     * after a call to {@link #stopAppSwitches()}.
1465     */
1466    long mAppSwitchesAllowedTime;
1467
1468    /**
1469     * This is set to true after the first switch after mAppSwitchesAllowedTime
1470     * is set; any switches after that will clear the time.
1471     */
1472    boolean mDidAppSwitch;
1473
1474    /**
1475     * Last time (in uptime) at which we checked for power usage.
1476     */
1477    long mLastPowerCheckUptime;
1478
1479    /**
1480     * Set while we are wanting to sleep, to prevent any
1481     * activities from being started/resumed.
1482     *
1483     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1484     *
1485     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1486     * while in the sleep state until there is a pending transition out of sleep, in which case
1487     * mSleeping is set to false, and remains false while awake.
1488     *
1489     * Whether mSleeping can quickly toggled between true/false without the device actually
1490     * display changing states is undefined.
1491     */
1492    private boolean mSleeping = false;
1493
1494    /**
1495     * The process state used for processes that are running the top activities.
1496     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1497     */
1498    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1499
1500    /**
1501     * Set while we are running a voice interaction.  This overrides
1502     * sleeping while it is active.
1503     */
1504    IVoiceInteractionSession mRunningVoice;
1505
1506    /**
1507     * For some direct access we need to power manager.
1508     */
1509    PowerManagerInternal mLocalPowerManager;
1510
1511    /**
1512     * We want to hold a wake lock while running a voice interaction session, since
1513     * this may happen with the screen off and we need to keep the CPU running to
1514     * be able to continue to interact with the user.
1515     */
1516    PowerManager.WakeLock mVoiceWakeLock;
1517
1518    /**
1519     * State of external calls telling us if the device is awake or asleep.
1520     */
1521    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1522
1523    /**
1524     * Set if we are shutting down the system, similar to sleeping.
1525     */
1526    boolean mShuttingDown = false;
1527
1528    /**
1529     * Current sequence id for oom_adj computation traversal.
1530     */
1531    int mAdjSeq = 0;
1532
1533    /**
1534     * Current sequence id for process LRU updating.
1535     */
1536    int mLruSeq = 0;
1537
1538    /**
1539     * Keep track of the non-cached/empty process we last found, to help
1540     * determine how to distribute cached/empty processes next time.
1541     */
1542    int mNumNonCachedProcs = 0;
1543
1544    /**
1545     * Keep track of the number of cached hidden procs, to balance oom adj
1546     * distribution between those and empty procs.
1547     */
1548    int mNumCachedHiddenProcs = 0;
1549
1550    /**
1551     * Keep track of the number of service processes we last found, to
1552     * determine on the next iteration which should be B services.
1553     */
1554    int mNumServiceProcs = 0;
1555    int mNewNumAServiceProcs = 0;
1556    int mNewNumServiceProcs = 0;
1557
1558    /**
1559     * Allow the current computed overall memory level of the system to go down?
1560     * This is set to false when we are killing processes for reasons other than
1561     * memory management, so that the now smaller process list will not be taken as
1562     * an indication that memory is tighter.
1563     */
1564    boolean mAllowLowerMemLevel = false;
1565
1566    /**
1567     * The last computed memory level, for holding when we are in a state that
1568     * processes are going away for other reasons.
1569     */
1570    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1571
1572    /**
1573     * The last total number of process we have, to determine if changes actually look
1574     * like a shrinking number of process due to lower RAM.
1575     */
1576    int mLastNumProcesses;
1577
1578    /**
1579     * The uptime of the last time we performed idle maintenance.
1580     */
1581    long mLastIdleTime = SystemClock.uptimeMillis();
1582
1583    /**
1584     * Total time spent with RAM that has been added in the past since the last idle time.
1585     */
1586    long mLowRamTimeSinceLastIdle = 0;
1587
1588    /**
1589     * If RAM is currently low, when that horrible situation started.
1590     */
1591    long mLowRamStartTime = 0;
1592
1593    /**
1594     * For reporting to battery stats the current top application.
1595     */
1596    private String mCurResumedPackage = null;
1597    private int mCurResumedUid = -1;
1598
1599    /**
1600     * For reporting to battery stats the apps currently running foreground
1601     * service.  The ProcessMap is package/uid tuples; each of these contain
1602     * an array of the currently foreground processes.
1603     */
1604    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1605            = new ProcessMap<ArrayList<ProcessRecord>>();
1606
1607    /**
1608     * Set if the systemServer made a call to enterSafeMode.
1609     */
1610    boolean mSafeMode;
1611
1612    /**
1613     * If true, we are running under a test environment so will sample PSS from processes
1614     * much more rapidly to try to collect better data when the tests are rapidly
1615     * running through apps.
1616     */
1617    boolean mTestPssMode = false;
1618
1619    String mDebugApp = null;
1620    boolean mWaitForDebugger = false;
1621    boolean mDebugTransient = false;
1622    String mOrigDebugApp = null;
1623    boolean mOrigWaitForDebugger = false;
1624    boolean mAlwaysFinishActivities = false;
1625    boolean mForceResizableActivities;
1626    /**
1627     * Flag that indicates if multi-window is enabled.
1628     *
1629     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1630     * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1631     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1632     * At least one of the forms of multi-window must be enabled in order for this flag to be
1633     * initialized to 'true'.
1634     *
1635     * @see #mSupportsSplitScreenMultiWindow
1636     * @see #mSupportsFreeformWindowManagement
1637     * @see #mSupportsPictureInPicture
1638     * @see #mSupportsMultiDisplay
1639     */
1640    boolean mSupportsMultiWindow;
1641    boolean mSupportsSplitScreenMultiWindow;
1642    boolean mSupportsFreeformWindowManagement;
1643    boolean mSupportsPictureInPicture;
1644    boolean mSupportsMultiDisplay;
1645    boolean mSupportsLeanbackOnly;
1646    IActivityController mController = null;
1647    boolean mControllerIsAMonkey = false;
1648    String mProfileApp = null;
1649    ProcessRecord mProfileProc = null;
1650    ProfilerInfo mProfilerInfo = null;
1651
1652    /**
1653     * Stores a map of process name -> agent string. When a process is started and mAgentAppMap
1654     * is not null, this map is checked and the mapped agent installed during bind-time. Note:
1655     * A non-null agent in mProfileInfo overrides this.
1656     */
1657    private @Nullable Map<String, String> mAppAgentMap = null;
1658
1659    int mProfileType = 0;
1660    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1661    String mMemWatchDumpProcName;
1662    String mMemWatchDumpFile;
1663    int mMemWatchDumpPid;
1664    int mMemWatchDumpUid;
1665    String mTrackAllocationApp = null;
1666    String mNativeDebuggingApp = null;
1667
1668    final long[] mTmpLong = new long[3];
1669
1670    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1671
1672    /**
1673     * A global counter for generating sequence numbers.
1674     * This value will be used when incrementing sequence numbers in individual uidRecords.
1675     *
1676     * Having a global counter ensures that seq numbers are monotonically increasing for a
1677     * particular uid even when the uidRecord is re-created.
1678     */
1679    @GuardedBy("this")
1680    @VisibleForTesting
1681    long mProcStateSeqCounter = 0;
1682
1683    /**
1684     * A global counter for generating sequence numbers to uniquely identify pending process starts.
1685     */
1686    @GuardedBy("this")
1687    private long mProcStartSeqCounter = 0;
1688
1689    /**
1690     * Contains {@link ProcessRecord} objects for pending process starts.
1691     *
1692     * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
1693     */
1694    @GuardedBy("this")
1695    private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
1696
1697    private final Injector mInjector;
1698
1699    static final class ProcessChangeItem {
1700        static final int CHANGE_ACTIVITIES = 1<<0;
1701        int changes;
1702        int uid;
1703        int pid;
1704        int processState;
1705        boolean foregroundActivities;
1706    }
1707
1708    static final class UidObserverRegistration {
1709        final int uid;
1710        final String pkg;
1711        final int which;
1712        final int cutpoint;
1713
1714        /**
1715         * Total # of callback calls that took more than {@link #SLOW_UID_OBSERVER_THRESHOLD_MS}.
1716         * We show it in dumpsys.
1717         */
1718        int mSlowDispatchCount;
1719
1720        /** Max time it took for each dispatch. */
1721        int mMaxDispatchTime;
1722
1723        final SparseIntArray lastProcStates;
1724
1725        // Please keep the enum lists in sync
1726        private static int[] ORIG_ENUMS = new int[]{
1727                ActivityManager.UID_OBSERVER_IDLE,
1728                ActivityManager.UID_OBSERVER_ACTIVE,
1729                ActivityManager.UID_OBSERVER_GONE,
1730                ActivityManager.UID_OBSERVER_PROCSTATE,
1731        };
1732        private static int[] PROTO_ENUMS = new int[]{
1733                ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
1734                ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
1735                ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
1736                ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
1737        };
1738
1739        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1740            uid = _uid;
1741            pkg = _pkg;
1742            which = _which;
1743            cutpoint = _cutpoint;
1744            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1745                lastProcStates = new SparseIntArray();
1746            } else {
1747                lastProcStates = null;
1748            }
1749        }
1750
1751        void writeToProto(ProtoOutputStream proto, long fieldId) {
1752            final long token = proto.start(fieldId);
1753            proto.write(UidObserverRegistrationProto.UID, uid);
1754            proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
1755            ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
1756                    which, ORIG_ENUMS, PROTO_ENUMS);
1757            proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
1758            if (lastProcStates != null) {
1759                final int NI = lastProcStates.size();
1760                for (int i=0; i<NI; i++) {
1761                    final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
1762                    proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i));
1763                    proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i));
1764                    proto.end(pToken);
1765                }
1766            }
1767            proto.end(token);
1768        }
1769    }
1770
1771    final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1772
1773    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1774    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1775
1776    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1777    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1778
1779    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1780    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1781
1782    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1783    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1784
1785    OomAdjObserver mCurOomAdjObserver;
1786    int mCurOomAdjUid;
1787
1788    interface OomAdjObserver {
1789        void onOomAdjMessage(String msg);
1790    }
1791
1792    /**
1793     * Runtime CPU use collection thread.  This object's lock is used to
1794     * perform synchronization with the thread (notifying it to run).
1795     */
1796    final Thread mProcessCpuThread;
1797
1798    /**
1799     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1800     * Must acquire this object's lock when accessing it.
1801     * NOTE: this lock will be held while doing long operations (trawling
1802     * through all processes in /proc), so it should never be acquired by
1803     * any critical paths such as when holding the main activity manager lock.
1804     */
1805    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1806            MONITOR_THREAD_CPU_USAGE);
1807    final AtomicLong mLastCpuTime = new AtomicLong(0);
1808    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1809    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1810
1811    long mLastWriteTime = 0;
1812
1813    /**
1814     * Used to retain an update lock when the foreground activity is in
1815     * immersive mode.
1816     */
1817    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1818
1819    /**
1820     * Set to true after the system has finished booting.
1821     */
1822    boolean mBooted = false;
1823
1824    WindowManagerService mWindowManager;
1825    final ActivityThread mSystemThread;
1826
1827    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1828        final ProcessRecord mApp;
1829        final int mPid;
1830        final IApplicationThread mAppThread;
1831
1832        AppDeathRecipient(ProcessRecord app, int pid,
1833                IApplicationThread thread) {
1834            if (DEBUG_ALL) Slog.v(
1835                TAG, "New death recipient " + this
1836                + " for thread " + thread.asBinder());
1837            mApp = app;
1838            mPid = pid;
1839            mAppThread = thread;
1840        }
1841
1842        @Override
1843        public void binderDied() {
1844            if (DEBUG_ALL) Slog.v(
1845                TAG, "Death received in " + this
1846                + " for thread " + mAppThread.asBinder());
1847            synchronized(ActivityManagerService.this) {
1848                appDiedLocked(mApp, mPid, mAppThread, true);
1849            }
1850        }
1851    }
1852
1853    static final int SHOW_ERROR_UI_MSG = 1;
1854    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1855    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1856    static final int UPDATE_CONFIGURATION_MSG = 4;
1857    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1858    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1859    static final int SERVICE_TIMEOUT_MSG = 12;
1860    static final int UPDATE_TIME_ZONE = 13;
1861    static final int SHOW_UID_ERROR_UI_MSG = 14;
1862    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1863    static final int PROC_START_TIMEOUT_MSG = 20;
1864    static final int KILL_APPLICATION_MSG = 22;
1865    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1866    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1867    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1868    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1869    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1870    static final int CLEAR_DNS_CACHE_MSG = 28;
1871    static final int UPDATE_HTTP_PROXY_MSG = 29;
1872    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1873    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1874    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1875    static final int REPORT_MEM_USAGE_MSG = 33;
1876    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1877    static final int PERSIST_URI_GRANTS_MSG = 38;
1878    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1879    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1880    static final int FINISH_BOOTING_MSG = 45;
1881    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1882    static final int DISMISS_DIALOG_UI_MSG = 48;
1883    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1884    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1885    static final int DELETE_DUMPHEAP_MSG = 51;
1886    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1887    static final int REPORT_TIME_TRACKER_MSG = 54;
1888    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1889    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1890    static final int IDLE_UIDS_MSG = 58;
1891    static final int LOG_STACK_STATE = 60;
1892    static final int VR_MODE_CHANGE_MSG = 61;
1893    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1894    static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
1895    static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
1896    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1897    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1898    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1899    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1900    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1901
1902    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1903    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1904    static final int FIRST_COMPAT_MODE_MSG = 300;
1905    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1906
1907    static ServiceThread sKillThread = null;
1908    static KillHandler sKillHandler = null;
1909
1910    CompatModeDialog mCompatModeDialog;
1911    long mLastMemUsageReportTime = 0;
1912
1913    /**
1914     * Flag whether the current user is a "monkey", i.e. whether
1915     * the UI is driven by a UI automation tool.
1916     */
1917    private boolean mUserIsMonkey;
1918
1919    /** The dimensions of the thumbnails in the Recents UI. */
1920    int mThumbnailWidth;
1921    int mThumbnailHeight;
1922    float mFullscreenThumbnailScale;
1923
1924    final ServiceThread mHandlerThread;
1925    final MainHandler mHandler;
1926    final Handler mUiHandler;
1927    final ServiceThread mProcStartHandlerThread;
1928    final Handler mProcStartHandler;
1929
1930    final ActivityManagerConstants mConstants;
1931
1932    // Encapsulates the global setting "hidden_api_blacklist_exemptions"
1933    final HiddenApiBlacklist mHiddenApiBlacklist;
1934
1935    PackageManagerInternal mPackageManagerInt;
1936
1937    // VoiceInteraction session ID that changes for each new request except when
1938    // being called for multiwindow assist in a single session.
1939    private int mViSessionId = 1000;
1940
1941    final boolean mPermissionReviewRequired;
1942
1943    /**
1944     * Whether to force background check on all apps (for battery saver) or not.
1945     */
1946    boolean mForceBackgroundCheck;
1947
1948    private static String sTheRealBuildSerial = Build.UNKNOWN;
1949
1950    /**
1951     * Current global configuration information. Contains general settings for the entire system,
1952     * also corresponds to the merged configuration of the default display.
1953     */
1954    Configuration getGlobalConfiguration() {
1955        return mStackSupervisor.getConfiguration();
1956    }
1957
1958    final class KillHandler extends Handler {
1959        static final int KILL_PROCESS_GROUP_MSG = 4000;
1960
1961        public KillHandler(Looper looper) {
1962            super(looper, null, true);
1963        }
1964
1965        @Override
1966        public void handleMessage(Message msg) {
1967            switch (msg.what) {
1968                case KILL_PROCESS_GROUP_MSG:
1969                {
1970                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1971                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1972                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1973                }
1974                break;
1975
1976                default:
1977                    super.handleMessage(msg);
1978            }
1979        }
1980    }
1981
1982    final class UiHandler extends Handler {
1983        public UiHandler() {
1984            super(com.android.server.UiThread.get().getLooper(), null, true);
1985        }
1986
1987        @Override
1988        public void handleMessage(Message msg) {
1989            switch (msg.what) {
1990            case SHOW_ERROR_UI_MSG: {
1991                mAppErrors.handleShowAppErrorUi(msg);
1992                ensureBootCompleted();
1993            } break;
1994            case SHOW_NOT_RESPONDING_UI_MSG: {
1995                mAppErrors.handleShowAnrUi(msg);
1996                ensureBootCompleted();
1997            } break;
1998            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1999                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
2000                synchronized (ActivityManagerService.this) {
2001                    ProcessRecord proc = (ProcessRecord) data.get("app");
2002                    if (proc == null) {
2003                        Slog.e(TAG, "App not found when showing strict mode dialog.");
2004                        break;
2005                    }
2006                    if (proc.crashDialog != null) {
2007                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
2008                        return;
2009                    }
2010                    AppErrorResult res = (AppErrorResult) data.get("result");
2011                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
2012                        Dialog d = new StrictModeViolationDialog(mUiContext,
2013                                ActivityManagerService.this, res, proc);
2014                        d.show();
2015                        proc.crashDialog = d;
2016                    } else {
2017                        // The device is asleep, so just pretend that the user
2018                        // saw a crash dialog and hit "force quit".
2019                        res.set(0);
2020                    }
2021                }
2022                ensureBootCompleted();
2023            } break;
2024            case SHOW_FACTORY_ERROR_UI_MSG: {
2025                Dialog d = new FactoryErrorDialog(
2026                        mUiContext, msg.getData().getCharSequence("msg"));
2027                d.show();
2028                ensureBootCompleted();
2029            } break;
2030            case WAIT_FOR_DEBUGGER_UI_MSG: {
2031                synchronized (ActivityManagerService.this) {
2032                    ProcessRecord app = (ProcessRecord)msg.obj;
2033                    if (msg.arg1 != 0) {
2034                        if (!app.waitedForDebugger) {
2035                            Dialog d = new AppWaitingForDebuggerDialog(
2036                                    ActivityManagerService.this,
2037                                    mUiContext, app);
2038                            app.waitDialog = d;
2039                            app.waitedForDebugger = true;
2040                            d.show();
2041                        }
2042                    } else {
2043                        if (app.waitDialog != null) {
2044                            app.waitDialog.dismiss();
2045                            app.waitDialog = null;
2046                        }
2047                    }
2048                }
2049            } break;
2050            case SHOW_UID_ERROR_UI_MSG: {
2051                if (mShowDialogs) {
2052                    AlertDialog d = new BaseErrorDialog(mUiContext);
2053                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2054                    d.setCancelable(false);
2055                    d.setTitle(mUiContext.getText(R.string.android_system_label));
2056                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
2057                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2058                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2059                    d.show();
2060                }
2061            } break;
2062            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
2063                if (mShowDialogs) {
2064                    AlertDialog d = new BaseErrorDialog(mUiContext);
2065                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
2066                    d.setCancelable(false);
2067                    d.setTitle(mUiContext.getText(R.string.android_system_label));
2068                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
2069                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
2070                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
2071                    d.show();
2072                }
2073            } break;
2074            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
2075                synchronized (ActivityManagerService.this) {
2076                    ActivityRecord ar = (ActivityRecord) msg.obj;
2077                    if (mCompatModeDialog != null) {
2078                        if (mCompatModeDialog.mAppInfo.packageName.equals(
2079                                ar.info.applicationInfo.packageName)) {
2080                            return;
2081                        }
2082                        mCompatModeDialog.dismiss();
2083                        mCompatModeDialog = null;
2084                    }
2085                    if (ar != null && false) {
2086                        if (mCompatModePackages.getPackageAskCompatModeLocked(
2087                                ar.packageName)) {
2088                            int mode = mCompatModePackages.computeCompatModeLocked(
2089                                    ar.info.applicationInfo);
2090                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
2091                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
2092                                mCompatModeDialog = new CompatModeDialog(
2093                                        ActivityManagerService.this, mUiContext,
2094                                        ar.info.applicationInfo);
2095                                mCompatModeDialog.show();
2096                            }
2097                        }
2098                    }
2099                }
2100                break;
2101            }
2102            case DISMISS_DIALOG_UI_MSG: {
2103                final Dialog d = (Dialog) msg.obj;
2104                d.dismiss();
2105                break;
2106            }
2107            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
2108                dispatchProcessesChanged();
2109                break;
2110            }
2111            case DISPATCH_PROCESS_DIED_UI_MSG: {
2112                final int pid = msg.arg1;
2113                final int uid = msg.arg2;
2114                dispatchProcessDied(pid, uid);
2115                break;
2116            }
2117            case DISPATCH_UIDS_CHANGED_UI_MSG: {
2118                dispatchUidsChanged();
2119            } break;
2120            case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
2121                dispatchOomAdjObserver((String)msg.obj);
2122            } break;
2123            case PUSH_TEMP_WHITELIST_UI_MSG: {
2124                pushTempWhitelist();
2125            } break;
2126            }
2127        }
2128    }
2129
2130    final class MainHandler extends Handler {
2131        public MainHandler(Looper looper) {
2132            super(looper, null, true);
2133        }
2134
2135        @Override
2136        public void handleMessage(Message msg) {
2137            switch (msg.what) {
2138            case UPDATE_CONFIGURATION_MSG: {
2139                final ContentResolver resolver = mContext.getContentResolver();
2140                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
2141                        msg.arg1);
2142            } break;
2143            case GC_BACKGROUND_PROCESSES_MSG: {
2144                synchronized (ActivityManagerService.this) {
2145                    performAppGcsIfAppropriateLocked();
2146                }
2147            } break;
2148            case SERVICE_TIMEOUT_MSG: {
2149                mServices.serviceTimeout((ProcessRecord)msg.obj);
2150            } break;
2151            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
2152                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
2153            } break;
2154            case SERVICE_FOREGROUND_CRASH_MSG: {
2155                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
2156            } break;
2157            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
2158                RemoteCallbackList<IResultReceiver> callbacks
2159                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
2160                int N = callbacks.beginBroadcast();
2161                for (int i = 0; i < N; i++) {
2162                    try {
2163                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
2164                    } catch (RemoteException e) {
2165                    }
2166                }
2167                callbacks.finishBroadcast();
2168            } break;
2169            case UPDATE_TIME_ZONE: {
2170                synchronized (ActivityManagerService.this) {
2171                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2172                        ProcessRecord r = mLruProcesses.get(i);
2173                        if (r.thread != null) {
2174                            try {
2175                                r.thread.updateTimeZone();
2176                            } catch (RemoteException ex) {
2177                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2178                            }
2179                        }
2180                    }
2181                }
2182            } break;
2183            case CLEAR_DNS_CACHE_MSG: {
2184                synchronized (ActivityManagerService.this) {
2185                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2186                        ProcessRecord r = mLruProcesses.get(i);
2187                        if (r.thread != null) {
2188                            try {
2189                                r.thread.clearDnsCache();
2190                            } catch (RemoteException ex) {
2191                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2192                            }
2193                        }
2194                    }
2195                }
2196            } break;
2197            case UPDATE_HTTP_PROXY_MSG: {
2198                ProxyInfo proxy = (ProxyInfo)msg.obj;
2199                String host = "";
2200                String port = "";
2201                String exclList = "";
2202                Uri pacFileUrl = Uri.EMPTY;
2203                if (proxy != null) {
2204                    host = proxy.getHost();
2205                    port = Integer.toString(proxy.getPort());
2206                    exclList = proxy.getExclusionListAsString();
2207                    pacFileUrl = proxy.getPacFileUrl();
2208                }
2209                synchronized (ActivityManagerService.this) {
2210                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2211                        ProcessRecord r = mLruProcesses.get(i);
2212                        // Don't dispatch to isolated processes as they can't access
2213                        // ConnectivityManager and don't have network privileges anyway.
2214                        if (r.thread != null && !r.isolated) {
2215                            try {
2216                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2217                            } catch (RemoteException ex) {
2218                                Slog.w(TAG, "Failed to update http proxy for: " +
2219                                        r.info.processName);
2220                            }
2221                        }
2222                    }
2223                }
2224            } break;
2225            case PROC_START_TIMEOUT_MSG: {
2226                ProcessRecord app = (ProcessRecord)msg.obj;
2227                synchronized (ActivityManagerService.this) {
2228                    processStartTimedOutLocked(app);
2229                }
2230            } break;
2231            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2232                ProcessRecord app = (ProcessRecord)msg.obj;
2233                synchronized (ActivityManagerService.this) {
2234                    processContentProviderPublishTimedOutLocked(app);
2235                }
2236            } break;
2237            case KILL_APPLICATION_MSG: {
2238                synchronized (ActivityManagerService.this) {
2239                    final int appId = msg.arg1;
2240                    final int userId = msg.arg2;
2241                    Bundle bundle = (Bundle)msg.obj;
2242                    String pkg = bundle.getString("pkg");
2243                    String reason = bundle.getString("reason");
2244                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2245                            false, userId, reason);
2246                }
2247            } break;
2248            case FINALIZE_PENDING_INTENT_MSG: {
2249                ((PendingIntentRecord)msg.obj).completeFinalize();
2250            } break;
2251            case POST_HEAVY_NOTIFICATION_MSG: {
2252                INotificationManager inm = NotificationManager.getService();
2253                if (inm == null) {
2254                    return;
2255                }
2256
2257                ActivityRecord root = (ActivityRecord)msg.obj;
2258                ProcessRecord process = root.app;
2259                if (process == null) {
2260                    return;
2261                }
2262
2263                try {
2264                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2265                    String text = mContext.getString(R.string.heavy_weight_notification,
2266                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2267                    Notification notification =
2268                            new Notification.Builder(context,
2269                                    SystemNotificationChannels.HEAVY_WEIGHT_APP)
2270                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2271                            .setWhen(0)
2272                            .setOngoing(true)
2273                            .setTicker(text)
2274                            .setColor(mContext.getColor(
2275                                    com.android.internal.R.color.system_notification_accent_color))
2276                            .setContentTitle(text)
2277                            .setContentText(
2278                                    mContext.getText(R.string.heavy_weight_notification_detail))
2279                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2280                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2281                                    new UserHandle(root.userId)))
2282                            .build();
2283                    try {
2284                        inm.enqueueNotificationWithTag("android", "android", null,
2285                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2286                                notification, root.userId);
2287                    } catch (RuntimeException e) {
2288                        Slog.w(ActivityManagerService.TAG,
2289                                "Error showing notification for heavy-weight app", e);
2290                    } catch (RemoteException e) {
2291                    }
2292                } catch (NameNotFoundException e) {
2293                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2294                }
2295            } break;
2296            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2297                INotificationManager inm = NotificationManager.getService();
2298                if (inm == null) {
2299                    return;
2300                }
2301                try {
2302                    inm.cancelNotificationWithTag("android", null,
2303                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1);
2304                } catch (RuntimeException e) {
2305                    Slog.w(ActivityManagerService.TAG,
2306                            "Error canceling notification for service", e);
2307                } catch (RemoteException e) {
2308                }
2309            } break;
2310            case CHECK_EXCESSIVE_POWER_USE_MSG: {
2311                synchronized (ActivityManagerService.this) {
2312                    checkExcessivePowerUsageLocked();
2313                    removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2314                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2315                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2316                }
2317            } break;
2318            case REPORT_MEM_USAGE_MSG: {
2319                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2320                Thread thread = new Thread() {
2321                    @Override public void run() {
2322                        reportMemUsage(memInfos);
2323                    }
2324                };
2325                thread.start();
2326                break;
2327            }
2328            case IMMERSIVE_MODE_LOCK_MSG: {
2329                final boolean nextState = (msg.arg1 != 0);
2330                if (mUpdateLock.isHeld() != nextState) {
2331                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2332                            "Applying new update lock state '" + nextState
2333                            + "' for " + (ActivityRecord)msg.obj);
2334                    if (nextState) {
2335                        mUpdateLock.acquire();
2336                    } else {
2337                        mUpdateLock.release();
2338                    }
2339                }
2340                break;
2341            }
2342            case PERSIST_URI_GRANTS_MSG: {
2343                writeGrantedUriPermissions();
2344                break;
2345            }
2346            case UPDATE_TIME_PREFERENCE_MSG: {
2347                // The user's time format preference might have changed.
2348                // For convenience we re-use the Intent extra values.
2349                synchronized (ActivityManagerService.this) {
2350                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2351                        ProcessRecord r = mLruProcesses.get(i);
2352                        if (r.thread != null) {
2353                            try {
2354                                r.thread.updateTimePrefs(msg.arg1);
2355                            } catch (RemoteException ex) {
2356                                Slog.w(TAG, "Failed to update preferences for: "
2357                                        + r.info.processName);
2358                            }
2359                        }
2360                    }
2361                }
2362                break;
2363            }
2364            case ENTER_ANIMATION_COMPLETE_MSG: {
2365                synchronized (ActivityManagerService.this) {
2366                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2367                    if (r != null && r.app != null && r.app.thread != null) {
2368                        try {
2369                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2370                        } catch (RemoteException e) {
2371                        }
2372                    }
2373                }
2374                break;
2375            }
2376            case FINISH_BOOTING_MSG: {
2377                if (msg.arg1 != 0) {
2378                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2379                    finishBooting();
2380                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2381                }
2382                if (msg.arg2 != 0) {
2383                    enableScreenAfterBoot();
2384                }
2385                break;
2386            }
2387            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2388                try {
2389                    Locale l = (Locale) msg.obj;
2390                    IBinder service = ServiceManager.getService("mount");
2391                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2392                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2393                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2394                } catch (RemoteException e) {
2395                    Log.e(TAG, "Error storing locale for decryption UI", e);
2396                }
2397                break;
2398            }
2399            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2400                final int uid = msg.arg1;
2401                final byte[] firstPacket = (byte[]) msg.obj;
2402
2403                synchronized (mPidsSelfLocked) {
2404                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2405                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2406                        if (p.uid == uid) {
2407                            try {
2408                                p.thread.notifyCleartextNetwork(firstPacket);
2409                            } catch (RemoteException ignored) {
2410                            }
2411                        }
2412                    }
2413                }
2414                break;
2415            }
2416            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2417                final String procName;
2418                final int uid;
2419                final long memLimit;
2420                final String reportPackage;
2421                synchronized (ActivityManagerService.this) {
2422                    procName = mMemWatchDumpProcName;
2423                    uid = mMemWatchDumpUid;
2424                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2425                    if (val == null) {
2426                        val = mMemWatchProcesses.get(procName, 0);
2427                    }
2428                    if (val != null) {
2429                        memLimit = val.first;
2430                        reportPackage = val.second;
2431                    } else {
2432                        memLimit = 0;
2433                        reportPackage = null;
2434                    }
2435                }
2436                if (procName == null) {
2437                    return;
2438                }
2439
2440                if (DEBUG_PSS) Slog.d(TAG_PSS,
2441                        "Showing dump heap notification from " + procName + "/" + uid);
2442
2443                INotificationManager inm = NotificationManager.getService();
2444                if (inm == null) {
2445                    return;
2446                }
2447
2448                String text = mContext.getString(R.string.dump_heap_notification, procName);
2449
2450
2451                Intent deleteIntent = new Intent();
2452                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2453                Intent intent = new Intent();
2454                intent.setClassName("android", DumpHeapActivity.class.getName());
2455                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2456                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2457                if (reportPackage != null) {
2458                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2459                }
2460                int userId = UserHandle.getUserId(uid);
2461                Notification notification =
2462                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2463                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2464                        .setWhen(0)
2465                        .setOngoing(true)
2466                        .setAutoCancel(true)
2467                        .setTicker(text)
2468                        .setColor(mContext.getColor(
2469                                com.android.internal.R.color.system_notification_accent_color))
2470                        .setContentTitle(text)
2471                        .setContentText(
2472                                mContext.getText(R.string.dump_heap_notification_detail))
2473                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2474                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2475                                new UserHandle(userId)))
2476                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2477                                deleteIntent, 0, UserHandle.SYSTEM))
2478                        .build();
2479
2480                try {
2481                    inm.enqueueNotificationWithTag("android", "android", null,
2482                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2483                            notification, userId);
2484                } catch (RuntimeException e) {
2485                    Slog.w(ActivityManagerService.TAG,
2486                            "Error showing notification for dump heap", e);
2487                } catch (RemoteException e) {
2488                }
2489            } break;
2490            case DELETE_DUMPHEAP_MSG: {
2491                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2492                        null, DumpHeapActivity.JAVA_URI,
2493                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2494                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2495                        UserHandle.myUserId());
2496                synchronized (ActivityManagerService.this) {
2497                    mMemWatchDumpFile = null;
2498                    mMemWatchDumpProcName = null;
2499                    mMemWatchDumpPid = -1;
2500                    mMemWatchDumpUid = -1;
2501                }
2502            } break;
2503            case REPORT_TIME_TRACKER_MSG: {
2504                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2505                tracker.deliverResult(mContext);
2506            } break;
2507            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2508                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2509                try {
2510                    connection.shutdown();
2511                } catch (RemoteException e) {
2512                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2513                }
2514                // Only a UiAutomation can set this flag and now that
2515                // it is finished we make sure it is reset to its default.
2516                mUserIsMonkey = false;
2517            } break;
2518            case IDLE_UIDS_MSG: {
2519                idleUids();
2520            } break;
2521            case VR_MODE_CHANGE_MSG: {
2522                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2523                    return;
2524                }
2525                synchronized (ActivityManagerService.this) {
2526                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2527                    mWindowManager.disableNonVrUi(disableNonVrUi);
2528                    if (disableNonVrUi) {
2529                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2530                        // then remove the pinned stack.
2531                        mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
2532                    }
2533                }
2534            } break;
2535            case DISPATCH_SCREEN_AWAKE_MSG: {
2536                final boolean isAwake = msg.arg1 != 0;
2537                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2538                    mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2539                }
2540            } break;
2541            case DISPATCH_SCREEN_KEYGUARD_MSG: {
2542                final boolean isShowing = msg.arg1 != 0;
2543                for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2544                    mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2545                }
2546            } break;
2547            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2548                synchronized (ActivityManagerService.this) {
2549                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2550                        ProcessRecord r = mLruProcesses.get(i);
2551                        if (r.thread != null) {
2552                            try {
2553                                r.thread.handleTrustStorageUpdate();
2554                            } catch (RemoteException ex) {
2555                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2556                                        r.info.processName);
2557                            }
2558                        }
2559                    }
2560                }
2561            } break;
2562            }
2563        }
2564    };
2565
2566    static final int COLLECT_PSS_BG_MSG = 1;
2567
2568    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2569        @Override
2570        public void handleMessage(Message msg) {
2571            switch (msg.what) {
2572            case COLLECT_PSS_BG_MSG: {
2573                long start = SystemClock.uptimeMillis();
2574                MemInfoReader memInfo = null;
2575                synchronized (ActivityManagerService.this) {
2576                    if (mFullPssPending) {
2577                        mFullPssPending = false;
2578                        memInfo = new MemInfoReader();
2579                    }
2580                }
2581                if (memInfo != null) {
2582                    updateCpuStatsNow();
2583                    long nativeTotalPss = 0;
2584                    final List<ProcessCpuTracker.Stats> stats;
2585                    synchronized (mProcessCpuTracker) {
2586                        stats = mProcessCpuTracker.getStats( (st)-> {
2587                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2588                        });
2589                    }
2590                    final int N = stats.size();
2591                    for (int j = 0; j < N; j++) {
2592                        synchronized (mPidsSelfLocked) {
2593                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2594                                // This is one of our own processes; skip it.
2595                                continue;
2596                            }
2597                        }
2598                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2599                    }
2600                    memInfo.readMemInfo();
2601                    synchronized (ActivityManagerService.this) {
2602                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2603                                + (SystemClock.uptimeMillis()-start) + "ms");
2604                        final long cachedKb = memInfo.getCachedSizeKb();
2605                        final long freeKb = memInfo.getFreeSizeKb();
2606                        final long zramKb = memInfo.getZramTotalSizeKb();
2607                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2608                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2609                                kernelKb*1024, nativeTotalPss*1024);
2610                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2611                                nativeTotalPss);
2612                    }
2613                }
2614
2615                int num = 0;
2616                long[] tmp = new long[3];
2617                do {
2618                    ProcessRecord proc;
2619                    int procState;
2620                    int statType;
2621                    int pid;
2622                    long lastPssTime;
2623                    synchronized (ActivityManagerService.this) {
2624                        if (mPendingPssProcesses.size() <= 0) {
2625                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2626                                    "Collected pss of " + num + " processes in "
2627                                    + (SystemClock.uptimeMillis() - start) + "ms");
2628                            mPendingPssProcesses.clear();
2629                            return;
2630                        }
2631                        proc = mPendingPssProcesses.remove(0);
2632                        procState = proc.pssProcState;
2633                        statType = proc.pssStatType;
2634                        lastPssTime = proc.lastPssTime;
2635                        long now = SystemClock.uptimeMillis();
2636                        if (proc.thread != null && procState == proc.setProcState
2637                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2638                                        < now) {
2639                            pid = proc.pid;
2640                        } else {
2641                            ProcessList.abortNextPssTime(proc.procStateMemTracker);
2642                            if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2643                                    ": still need " +
2644                                    (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE-now) +
2645                                    "ms until safe");
2646                            proc = null;
2647                            pid = 0;
2648                        }
2649                    }
2650                    if (proc != null) {
2651                        long startTime = SystemClock.currentThreadTimeMillis();
2652                        long pss = Debug.getPss(pid, tmp, null);
2653                        long endTime = SystemClock.currentThreadTimeMillis();
2654                        synchronized (ActivityManagerService.this) {
2655                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2656                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2657                                num++;
2658                                ProcessList.commitNextPssTime(proc.procStateMemTracker);
2659                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], tmp[2],
2660                                        statType, endTime-startTime, SystemClock.uptimeMillis());
2661                            } else {
2662                                ProcessList.abortNextPssTime(proc.procStateMemTracker);
2663                                if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
2664                                        ": " + (proc.thread == null ? "NO_THREAD " : "") +
2665                                        (proc.pid != pid ? "PID_CHANGED " : "") +
2666                                        " initState=" + procState + " curState=" +
2667                                        proc.setProcState + " " +
2668                                        (proc.lastPssTime != lastPssTime ? "TIME_CHANGED" : ""));
2669                            }
2670                        }
2671                    }
2672                } while (true);
2673            }
2674            }
2675        }
2676    };
2677
2678    public void setSystemProcess() {
2679        try {
2680            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
2681                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
2682            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2683            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
2684                    DUMP_FLAG_PRIORITY_HIGH);
2685            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2686            ServiceManager.addService("dbinfo", new DbBinder(this));
2687            if (MONITOR_CPU_USAGE) {
2688                ServiceManager.addService("cpuinfo", new CpuBinder(this),
2689                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
2690            }
2691            ServiceManager.addService("permission", new PermissionController(this));
2692            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2693
2694            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2695                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2696            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2697
2698            synchronized (this) {
2699                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2700                app.persistent = true;
2701                app.pid = MY_PID;
2702                app.maxAdj = ProcessList.SYSTEM_ADJ;
2703                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2704                synchronized (mPidsSelfLocked) {
2705                    mPidsSelfLocked.put(app.pid, app);
2706                }
2707                updateLruProcessLocked(app, false, null);
2708                updateOomAdjLocked();
2709            }
2710        } catch (PackageManager.NameNotFoundException e) {
2711            throw new RuntimeException(
2712                    "Unable to find android system package", e);
2713        }
2714
2715        // Start watching app ops after we and the package manager are up and running.
2716        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2717                new IAppOpsCallback.Stub() {
2718                    @Override public void opChanged(int op, int uid, String packageName) {
2719                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2720                            if (mAppOpsService.checkOperation(op, uid, packageName)
2721                                    != AppOpsManager.MODE_ALLOWED) {
2722                                runInBackgroundDisabled(uid);
2723                            }
2724                        }
2725                    }
2726                });
2727    }
2728
2729    public void setWindowManager(WindowManagerService wm) {
2730        synchronized (this) {
2731            mWindowManager = wm;
2732            mStackSupervisor.setWindowManager(wm);
2733            mLockTaskController.setWindowManager(wm);
2734        }
2735    }
2736
2737    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2738        mUsageStatsService = usageStatsManager;
2739    }
2740
2741    public void startObservingNativeCrashes() {
2742        final NativeCrashListener ncl = new NativeCrashListener(this);
2743        ncl.start();
2744    }
2745
2746    public IAppOpsService getAppOpsService() {
2747        return mAppOpsService;
2748    }
2749
2750    static class MemBinder extends Binder {
2751        ActivityManagerService mActivityManagerService;
2752        private final PriorityDump.PriorityDumper mPriorityDumper =
2753                new PriorityDump.PriorityDumper() {
2754            @Override
2755            public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args,
2756                    boolean asProto) {
2757                dump(fd, pw, new String[] {"-a"}, asProto);
2758            }
2759
2760            @Override
2761            public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
2762                mActivityManagerService.dumpApplicationMemoryUsage(
2763                        fd, pw, "  ", args, false, null, asProto);
2764            }
2765        };
2766
2767        MemBinder(ActivityManagerService activityManagerService) {
2768            mActivityManagerService = activityManagerService;
2769        }
2770
2771        @Override
2772        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2773            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2774                    "meminfo", pw)) return;
2775            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2776        }
2777    }
2778
2779    static class GraphicsBinder extends Binder {
2780        ActivityManagerService mActivityManagerService;
2781        GraphicsBinder(ActivityManagerService activityManagerService) {
2782            mActivityManagerService = activityManagerService;
2783        }
2784
2785        @Override
2786        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2787            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2788                    "gfxinfo", pw)) return;
2789            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2790        }
2791    }
2792
2793    static class DbBinder extends Binder {
2794        ActivityManagerService mActivityManagerService;
2795        DbBinder(ActivityManagerService activityManagerService) {
2796            mActivityManagerService = activityManagerService;
2797        }
2798
2799        @Override
2800        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2801            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2802                    "dbinfo", pw)) return;
2803            mActivityManagerService.dumpDbInfo(fd, pw, args);
2804        }
2805    }
2806
2807    static class CpuBinder extends Binder {
2808        ActivityManagerService mActivityManagerService;
2809        private final PriorityDump.PriorityDumper mPriorityDumper =
2810                new PriorityDump.PriorityDumper() {
2811            @Override
2812            public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
2813                    boolean asProto) {
2814                if (asProto) return;
2815                if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2816                        "cpuinfo", pw)) return;
2817                synchronized (mActivityManagerService.mProcessCpuTracker) {
2818                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2819                    pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2820                            SystemClock.uptimeMillis()));
2821                }
2822            }
2823        };
2824
2825        CpuBinder(ActivityManagerService activityManagerService) {
2826            mActivityManagerService = activityManagerService;
2827        }
2828
2829        @Override
2830        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2831            PriorityDump.dump(mPriorityDumper, fd, pw, args);
2832        }
2833    }
2834
2835    public static final class Lifecycle extends SystemService {
2836        private final ActivityManagerService mService;
2837
2838        public Lifecycle(Context context) {
2839            super(context);
2840            mService = new ActivityManagerService(context);
2841        }
2842
2843        @Override
2844        public void onStart() {
2845            mService.start();
2846        }
2847
2848        @Override
2849        public void onBootPhase(int phase) {
2850            if (phase == PHASE_SYSTEM_SERVICES_READY) {
2851                mService.mBatteryStatsService.systemServicesReady();
2852            }
2853        }
2854
2855        @Override
2856        public void onCleanupUser(int userId) {
2857            mService.mBatteryStatsService.onCleanupUser(userId);
2858        }
2859
2860        public ActivityManagerService getService() {
2861            return mService;
2862        }
2863    }
2864
2865    /**
2866     * Encapsulates the globla setting "hidden_api_blacklist_exemptions", including tracking the
2867     * latest value via a content observer.
2868     */
2869    static class HiddenApiBlacklist extends ContentObserver {
2870
2871        private final Context mContext;
2872        private boolean mBlacklistDisabled;
2873
2874        public HiddenApiBlacklist(Handler handler, Context context) {
2875            super(handler);
2876            mContext = context;
2877        }
2878
2879        public void registerObserver() {
2880            mContext.getContentResolver().registerContentObserver(
2881                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS),
2882                    false,
2883                    this);
2884            update();
2885        }
2886
2887        private void update() {
2888            mBlacklistDisabled = "*".equals(Settings.Global.getString(mContext.getContentResolver(),
2889                    Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS));
2890        }
2891
2892        boolean isDisabled() {
2893            return mBlacklistDisabled;
2894        }
2895
2896        public void onChange(boolean selfChange) {
2897            update();
2898        }
2899    }
2900
2901    @VisibleForTesting
2902    public ActivityManagerService(Injector injector) {
2903        mInjector = injector;
2904        mContext = mInjector.getContext();
2905        mUiContext = null;
2906        GL_ES_VERSION = 0;
2907        mActivityStartController = null;
2908        mAppErrors = null;
2909        mAppWarnings = null;
2910        mAppOpsService = mInjector.getAppOpsService(null, null);
2911        mBatteryStatsService = null;
2912        mCompatModePackages = null;
2913        mConstants = null;
2914        mGrantFile = null;
2915        mHandler = null;
2916        mHandlerThread = null;
2917        mIntentFirewall = null;
2918        mKeyguardController = null;
2919        mPermissionReviewRequired = false;
2920        mProcessCpuThread = null;
2921        mProcessStats = null;
2922        mProviderMap = null;
2923        mRecentTasks = null;
2924        mServices = null;
2925        mStackSupervisor = null;
2926        mSystemThread = null;
2927        mTaskChangeNotificationController = null;
2928        mUiHandler = injector.getUiHandler(null);
2929        mUserController = null;
2930        mVrController = null;
2931        mLockTaskController = null;
2932        mLifecycleManager = null;
2933        mProcStartHandlerThread = null;
2934        mProcStartHandler = null;
2935        mHiddenApiBlacklist = null;
2936    }
2937
2938    // Note: This method is invoked on the main thread but may need to attach various
2939    // handlers to other threads.  So take care to be explicit about the looper.
2940    public ActivityManagerService(Context systemContext) {
2941        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2942        mInjector = new Injector();
2943        mContext = systemContext;
2944
2945        mFactoryTest = FactoryTest.getMode();
2946        mSystemThread = ActivityThread.currentActivityThread();
2947        mUiContext = mSystemThread.getSystemUiContext();
2948
2949        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2950
2951        mPermissionReviewRequired = mContext.getResources().getBoolean(
2952                com.android.internal.R.bool.config_permissionReviewRequired);
2953
2954        mHandlerThread = new ServiceThread(TAG,
2955                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2956        mHandlerThread.start();
2957        mHandler = new MainHandler(mHandlerThread.getLooper());
2958        mUiHandler = mInjector.getUiHandler(this);
2959
2960        mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
2961                THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
2962        mProcStartHandlerThread.start();
2963        mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
2964
2965        mConstants = new ActivityManagerConstants(this, mHandler);
2966
2967        /* static; one-time init here */
2968        if (sKillHandler == null) {
2969            sKillThread = new ServiceThread(TAG + ":kill",
2970                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2971            sKillThread.start();
2972            sKillHandler = new KillHandler(sKillThread.getLooper());
2973        }
2974
2975        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2976                "foreground", BROADCAST_FG_TIMEOUT, false);
2977        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2978                "background", BROADCAST_BG_TIMEOUT, true);
2979        mBroadcastQueues[0] = mFgBroadcastQueue;
2980        mBroadcastQueues[1] = mBgBroadcastQueue;
2981
2982        mServices = new ActiveServices(this);
2983        mProviderMap = new ProviderMap(this);
2984        mAppErrors = new AppErrors(mUiContext, this);
2985
2986        File dataDir = Environment.getDataDirectory();
2987        File systemDir = new File(dataDir, "system");
2988        systemDir.mkdirs();
2989
2990        mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
2991
2992        // TODO: Move creation of battery stats service outside of activity manager service.
2993        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2994        mBatteryStatsService.getActiveStatistics().readLocked();
2995        mBatteryStatsService.scheduleWriteToDisk();
2996        mOnBattery = DEBUG_POWER ? true
2997                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2998        mBatteryStatsService.getActiveStatistics().setCallback(this);
2999
3000        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
3001
3002        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
3003
3004        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
3005
3006        mUserController = new UserController(this);
3007
3008        mVrController = new VrController(this);
3009
3010        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
3011            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
3012
3013        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
3014            mUseFifoUiScheduling = true;
3015        }
3016
3017        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
3018        mTempConfig.setToDefaults();
3019        mTempConfig.setLocales(LocaleList.getDefault());
3020        mConfigurationSeq = mTempConfig.seq = 1;
3021        mStackSupervisor = createStackSupervisor();
3022        mStackSupervisor.onConfigurationChanged(mTempConfig);
3023        mKeyguardController = mStackSupervisor.getKeyguardController();
3024        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
3025        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
3026        mTaskChangeNotificationController =
3027                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
3028        mActivityStartController = new ActivityStartController(this);
3029        mRecentTasks = createRecentTasks();
3030        mStackSupervisor.setRecentTasks(mRecentTasks);
3031        mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mHandler);
3032        mLifecycleManager = new ClientLifecycleManager();
3033
3034        mProcessCpuThread = new Thread("CpuTracker") {
3035            @Override
3036            public void run() {
3037                synchronized (mProcessCpuTracker) {
3038                    mProcessCpuInitLatch.countDown();
3039                    mProcessCpuTracker.init();
3040                }
3041                while (true) {
3042                    try {
3043                        try {
3044                            synchronized(this) {
3045                                final long now = SystemClock.uptimeMillis();
3046                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
3047                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
3048                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
3049                                //        + ", write delay=" + nextWriteDelay);
3050                                if (nextWriteDelay < nextCpuDelay) {
3051                                    nextCpuDelay = nextWriteDelay;
3052                                }
3053                                if (nextCpuDelay > 0) {
3054                                    mProcessCpuMutexFree.set(true);
3055                                    this.wait(nextCpuDelay);
3056                                }
3057                            }
3058                        } catch (InterruptedException e) {
3059                        }
3060                        updateCpuStatsNow();
3061                    } catch (Exception e) {
3062                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
3063                    }
3064                }
3065            }
3066        };
3067
3068        mHiddenApiBlacklist = new HiddenApiBlacklist(mHandler, mContext);
3069
3070        Watchdog.getInstance().addMonitor(this);
3071        Watchdog.getInstance().addThread(mHandler);
3072
3073        // bind background thread to little cores
3074        // this is expected to fail inside of framework tests because apps can't touch cpusets directly
3075        try {
3076            Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(),
3077                    Process.THREAD_GROUP_BG_NONINTERACTIVE);
3078        } catch (Exception e) {
3079            Slog.w(TAG, "Setting background thread cpuset failed");
3080        }
3081
3082    }
3083
3084    protected ActivityStackSupervisor createStackSupervisor() {
3085        final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mHandler.getLooper());
3086        supervisor.initialize();
3087        return supervisor;
3088    }
3089
3090    protected RecentTasks createRecentTasks() {
3091        return new RecentTasks(this, mStackSupervisor);
3092    }
3093
3094    RecentTasks getRecentTasks() {
3095        return mRecentTasks;
3096    }
3097
3098    public void setSystemServiceManager(SystemServiceManager mgr) {
3099        mSystemServiceManager = mgr;
3100    }
3101
3102    public void setInstaller(Installer installer) {
3103        mInstaller = installer;
3104    }
3105
3106    private void start() {
3107        removeAllProcessGroups();
3108        mProcessCpuThread.start();
3109
3110        mBatteryStatsService.publish();
3111        mAppOpsService.publish(mContext);
3112        Slog.d("AppOps", "AppOpsService published");
3113        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
3114        // Wait for the synchronized block started in mProcessCpuThread,
3115        // so that any other acccess to mProcessCpuTracker from main thread
3116        // will be blocked during mProcessCpuTracker initialization.
3117        try {
3118            mProcessCpuInitLatch.await();
3119        } catch (InterruptedException e) {
3120            Slog.wtf(TAG, "Interrupted wait during start", e);
3121            Thread.currentThread().interrupt();
3122            throw new IllegalStateException("Interrupted wait during start");
3123        }
3124    }
3125
3126    void onUserStoppedLocked(int userId) {
3127        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
3128        mAllowAppSwitchUids.remove(userId);
3129    }
3130
3131    public void initPowerManagement() {
3132        mStackSupervisor.initPowerManagement();
3133        mBatteryStatsService.initPowerManagement();
3134        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
3135        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
3136        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
3137        mVoiceWakeLock.setReferenceCounted(false);
3138    }
3139
3140    private ArraySet<String> getBackgroundLaunchBroadcasts() {
3141        if (mBackgroundLaunchBroadcasts == null) {
3142            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
3143        }
3144        return mBackgroundLaunchBroadcasts;
3145    }
3146
3147    @Override
3148    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3149            throws RemoteException {
3150        if (code == SYSPROPS_TRANSACTION) {
3151            // We need to tell all apps about the system property change.
3152            ArrayList<IBinder> procs = new ArrayList<IBinder>();
3153            synchronized(this) {
3154                final int NP = mProcessNames.getMap().size();
3155                for (int ip=0; ip<NP; ip++) {
3156                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
3157                    final int NA = apps.size();
3158                    for (int ia=0; ia<NA; ia++) {
3159                        ProcessRecord app = apps.valueAt(ia);
3160                        if (app.thread != null) {
3161                            procs.add(app.thread.asBinder());
3162                        }
3163                    }
3164                }
3165            }
3166
3167            int N = procs.size();
3168            for (int i=0; i<N; i++) {
3169                Parcel data2 = Parcel.obtain();
3170                try {
3171                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
3172                            Binder.FLAG_ONEWAY);
3173                } catch (RemoteException e) {
3174                }
3175                data2.recycle();
3176            }
3177        }
3178        try {
3179            return super.onTransact(code, data, reply, flags);
3180        } catch (RuntimeException e) {
3181            // The activity manager only throws certain exceptions intentionally, so let's
3182            // log all others.
3183            if (!(e instanceof SecurityException
3184                    || e instanceof IllegalArgumentException
3185                    || e instanceof IllegalStateException)) {
3186                Slog.wtf(TAG, "Activity Manager Crash."
3187                        + " UID:" + Binder.getCallingUid()
3188                        + " PID:" + Binder.getCallingPid()
3189                        + " TRANS:" + code, e);
3190            }
3191            throw e;
3192        }
3193    }
3194
3195    void updateCpuStats() {
3196        final long now = SystemClock.uptimeMillis();
3197        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
3198            return;
3199        }
3200        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
3201            synchronized (mProcessCpuThread) {
3202                mProcessCpuThread.notify();
3203            }
3204        }
3205    }
3206
3207    void updateCpuStatsNow() {
3208        synchronized (mProcessCpuTracker) {
3209            mProcessCpuMutexFree.set(false);
3210            final long now = SystemClock.uptimeMillis();
3211            boolean haveNewCpuStats = false;
3212
3213            if (MONITOR_CPU_USAGE &&
3214                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
3215                mLastCpuTime.set(now);
3216                mProcessCpuTracker.update();
3217                if (mProcessCpuTracker.hasGoodLastStats()) {
3218                    haveNewCpuStats = true;
3219                    //Slog.i(TAG, mProcessCpu.printCurrentState());
3220                    //Slog.i(TAG, "Total CPU usage: "
3221                    //        + mProcessCpu.getTotalCpuPercent() + "%");
3222
3223                    // Slog the cpu usage if the property is set.
3224                    if ("true".equals(SystemProperties.get("events.cpu"))) {
3225                        int user = mProcessCpuTracker.getLastUserTime();
3226                        int system = mProcessCpuTracker.getLastSystemTime();
3227                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
3228                        int irq = mProcessCpuTracker.getLastIrqTime();
3229                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
3230                        int idle = mProcessCpuTracker.getLastIdleTime();
3231
3232                        int total = user + system + iowait + irq + softIrq + idle;
3233                        if (total == 0) total = 1;
3234
3235                        EventLog.writeEvent(EventLogTags.CPU,
3236                                ((user+system+iowait+irq+softIrq) * 100) / total,
3237                                (user * 100) / total,
3238                                (system * 100) / total,
3239                                (iowait * 100) / total,
3240                                (irq * 100) / total,
3241                                (softIrq * 100) / total);
3242                    }
3243                }
3244            }
3245
3246            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3247            synchronized(bstats) {
3248                synchronized(mPidsSelfLocked) {
3249                    if (haveNewCpuStats) {
3250                        if (bstats.startAddingCpuLocked()) {
3251                            int totalUTime = 0;
3252                            int totalSTime = 0;
3253                            final int N = mProcessCpuTracker.countStats();
3254                            for (int i=0; i<N; i++) {
3255                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3256                                if (!st.working) {
3257                                    continue;
3258                                }
3259                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3260                                totalUTime += st.rel_utime;
3261                                totalSTime += st.rel_stime;
3262                                if (pr != null) {
3263                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3264                                    if (ps == null || !ps.isActive()) {
3265                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3266                                                pr.info.uid, pr.processName);
3267                                    }
3268                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3269                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3270                                    if (pr.lastCpuTime == 0) {
3271                                        pr.lastCpuTime = pr.curCpuTime;
3272                                    }
3273                                } else {
3274                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3275                                    if (ps == null || !ps.isActive()) {
3276                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3277                                                bstats.mapUid(st.uid), st.name);
3278                                    }
3279                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3280                                }
3281                            }
3282                            final int userTime = mProcessCpuTracker.getLastUserTime();
3283                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3284                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3285                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3286                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3287                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3288                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3289                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3290                        }
3291                    }
3292                }
3293
3294                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3295                    mLastWriteTime = now;
3296                    mBatteryStatsService.scheduleWriteToDisk();
3297                }
3298            }
3299        }
3300    }
3301
3302    @Override
3303    public void batteryNeedsCpuUpdate() {
3304        updateCpuStatsNow();
3305    }
3306
3307    @Override
3308    public void batteryPowerChanged(boolean onBattery) {
3309        // When plugging in, update the CPU stats first before changing
3310        // the plug state.
3311        updateCpuStatsNow();
3312        synchronized (this) {
3313            synchronized(mPidsSelfLocked) {
3314                mOnBattery = DEBUG_POWER ? true : onBattery;
3315            }
3316        }
3317    }
3318
3319    @Override
3320    public void batterySendBroadcast(Intent intent) {
3321        synchronized (this) {
3322            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3323                    OP_NONE, null, false, false,
3324                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3325        }
3326    }
3327
3328    /**
3329     * Initialize the application bind args. These are passed to each
3330     * process when the bindApplication() IPC is sent to the process. They're
3331     * lazily setup to make sure the services are running when they're asked for.
3332     */
3333    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3334        // Isolated processes won't get this optimization, so that we don't
3335        // violate the rules about which services they have access to.
3336        if (isolated) {
3337            if (mIsolatedAppBindArgs == null) {
3338                mIsolatedAppBindArgs = new HashMap<>();
3339                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3340            }
3341            return mIsolatedAppBindArgs;
3342        }
3343
3344        if (mAppBindArgs == null) {
3345            mAppBindArgs = new HashMap<>();
3346
3347            // Setup the application init args
3348            mAppBindArgs.put("package", ServiceManager.getService("package"));
3349            mAppBindArgs.put("window", ServiceManager.getService("window"));
3350            mAppBindArgs.put(Context.ALARM_SERVICE,
3351                    ServiceManager.getService(Context.ALARM_SERVICE));
3352        }
3353        return mAppBindArgs;
3354    }
3355
3356    /**
3357     * Update AMS states when an activity is resumed. This should only be called by
3358     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3359     */
3360    @GuardedBy("this")
3361    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3362        final TaskRecord task = r.getTask();
3363        if (task.isActivityTypeStandard()) {
3364            if (mCurAppTimeTracker != r.appTimeTracker) {
3365                // We are switching app tracking.  Complete the current one.
3366                if (mCurAppTimeTracker != null) {
3367                    mCurAppTimeTracker.stop();
3368                    mHandler.obtainMessage(
3369                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3370                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3371                    mCurAppTimeTracker = null;
3372                }
3373                if (r.appTimeTracker != null) {
3374                    mCurAppTimeTracker = r.appTimeTracker;
3375                    startTimeTrackingFocusedActivityLocked();
3376                }
3377            } else {
3378                startTimeTrackingFocusedActivityLocked();
3379            }
3380        } else {
3381            r.appTimeTracker = null;
3382        }
3383        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3384        // TODO: Probably not, because we don't want to resume voice on switching
3385        // back to this activity
3386        if (task.voiceInteractor != null) {
3387            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3388        } else {
3389            finishRunningVoiceLocked();
3390
3391            if (mLastResumedActivity != null) {
3392                final IVoiceInteractionSession session;
3393
3394                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3395                if (lastResumedActivityTask != null
3396                        && lastResumedActivityTask.voiceSession != null) {
3397                    session = lastResumedActivityTask.voiceSession;
3398                } else {
3399                    session = mLastResumedActivity.voiceSession;
3400                }
3401
3402                if (session != null) {
3403                    // We had been in a voice interaction session, but now focused has
3404                    // move to something different.  Just finish the session, we can't
3405                    // return to it and retain the proper state and synchronization with
3406                    // the voice interaction service.
3407                    finishVoiceTask(session);
3408                }
3409            }
3410        }
3411
3412        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3413            mUserController.sendForegroundProfileChanged(r.userId);
3414        }
3415        mLastResumedActivity = r;
3416
3417        mWindowManager.setFocusedApp(r.appToken, true);
3418
3419        applyUpdateLockStateLocked(r);
3420        applyUpdateVrModeLocked(r);
3421
3422        EventLogTags.writeAmSetResumedActivity(
3423                r == null ? -1 : r.userId,
3424                r == null ? "NULL" : r.shortComponentName,
3425                reason);
3426    }
3427
3428    @Override
3429    public void setFocusedStack(int stackId) {
3430        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3431        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3432        final long callingId = Binder.clearCallingIdentity();
3433        try {
3434            synchronized (this) {
3435                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3436                if (stack == null) {
3437                    Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
3438                    return;
3439                }
3440                final ActivityRecord r = stack.topRunningActivityLocked();
3441                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3442                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3443                }
3444            }
3445        } finally {
3446            Binder.restoreCallingIdentity(callingId);
3447        }
3448    }
3449
3450    @Override
3451    public void setFocusedTask(int taskId) {
3452        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3453        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3454        final long callingId = Binder.clearCallingIdentity();
3455        try {
3456            synchronized (this) {
3457                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3458                if (task == null) {
3459                    return;
3460                }
3461                final ActivityRecord r = task.topRunningActivityLocked();
3462                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3463                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3464                }
3465            }
3466        } finally {
3467            Binder.restoreCallingIdentity(callingId);
3468        }
3469    }
3470
3471    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3472    @Override
3473    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3474        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3475                "registerTaskStackListener()");
3476        mTaskChangeNotificationController.registerTaskStackListener(listener);
3477    }
3478
3479    /**
3480     * Unregister a task stack listener so that it stops receiving callbacks.
3481     */
3482    @Override
3483    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3484        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
3485                "unregisterTaskStackListener()");
3486         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3487     }
3488
3489    @Override
3490    public void notifyActivityDrawn(IBinder token) {
3491        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3492        synchronized (this) {
3493            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3494            if (r != null) {
3495                r.getStack().notifyActivityDrawnLocked(r);
3496            }
3497        }
3498    }
3499
3500    final void applyUpdateLockStateLocked(ActivityRecord r) {
3501        // Modifications to the UpdateLock state are done on our handler, outside
3502        // the activity manager's locks.  The new state is determined based on the
3503        // state *now* of the relevant activity record.  The object is passed to
3504        // the handler solely for logging detail, not to be consulted/modified.
3505        final boolean nextState = r != null && r.immersive;
3506        mHandler.sendMessage(
3507                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3508    }
3509
3510    final void applyUpdateVrModeLocked(ActivityRecord r) {
3511        // VR apps are expected to run in a main display. If an app is turning on VR for
3512        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3513        // fullscreen stack before enabling VR Mode.
3514        // TODO: The goal of this code is to keep the VR app on the main display. When the
3515        // stack implementation changes in the future, keep in mind that the use of the fullscreen
3516        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3517        // option would be a better choice here.
3518        if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
3519            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3520                    + " to main stack for VR");
3521            final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack(
3522                    WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
3523            moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */);
3524        }
3525        mHandler.sendMessage(
3526                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3527    }
3528
3529    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3530        Message msg = Message.obtain();
3531        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3532        msg.obj = r.getTask().askedCompatMode ? null : r;
3533        mUiHandler.sendMessage(msg);
3534    }
3535
3536    final AppWarnings getAppWarningsLocked() {
3537        return mAppWarnings;
3538    }
3539
3540    /**
3541     * Shows app warning dialogs, if necessary.
3542     *
3543     * @param r activity record for which the warnings may be displayed
3544     */
3545    final void showAppWarningsIfNeededLocked(ActivityRecord r) {
3546        mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
3547        mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
3548        mAppWarnings.showDeprecatedTargetDialogIfNeeded(r);
3549    }
3550
3551    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3552            String what, Object obj, ProcessRecord srcApp) {
3553        app.lastActivityTime = now;
3554
3555        if (app.activities.size() > 0 || app.recentTasks.size() > 0) {
3556            // Don't want to touch dependent processes that are hosting activities.
3557            return index;
3558        }
3559
3560        int lrui = mLruProcesses.lastIndexOf(app);
3561        if (lrui < 0) {
3562            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3563                    + what + " " + obj + " from " + srcApp);
3564            return index;
3565        }
3566
3567        if (lrui >= index) {
3568            // Don't want to cause this to move dependent processes *back* in the
3569            // list as if they were less frequently used.
3570            return index;
3571        }
3572
3573        if (lrui >= mLruProcessActivityStart) {
3574            // Don't want to touch dependent processes that are hosting activities.
3575            return index;
3576        }
3577
3578        mLruProcesses.remove(lrui);
3579        if (index > 0) {
3580            index--;
3581        }
3582        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3583                + " in LRU list: " + app);
3584        mLruProcesses.add(index, app);
3585        return index;
3586    }
3587
3588    static void killProcessGroup(int uid, int pid) {
3589        if (sKillHandler != null) {
3590            sKillHandler.sendMessage(
3591                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3592        } else {
3593            Slog.w(TAG, "Asked to kill process group before system bringup!");
3594            Process.killProcessGroup(uid, pid);
3595        }
3596    }
3597
3598    final void removeLruProcessLocked(ProcessRecord app) {
3599        int lrui = mLruProcesses.lastIndexOf(app);
3600        if (lrui >= 0) {
3601            if (!app.killed) {
3602                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3603                if (app.pid > 0) {
3604                    killProcessQuiet(app.pid);
3605                    killProcessGroup(app.uid, app.pid);
3606                } else {
3607                    app.pendingStart = false;
3608                }
3609            }
3610            if (lrui <= mLruProcessActivityStart) {
3611                mLruProcessActivityStart--;
3612            }
3613            if (lrui <= mLruProcessServiceStart) {
3614                mLruProcessServiceStart--;
3615            }
3616            mLruProcesses.remove(lrui);
3617        }
3618    }
3619
3620    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3621            ProcessRecord client) {
3622        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3623                || app.treatLikeActivity || app.recentTasks.size() > 0;
3624        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3625        if (!activityChange && hasActivity) {
3626            // The process has activities, so we are only allowing activity-based adjustments
3627            // to move it.  It should be kept in the front of the list with other
3628            // processes that have activities, and we don't want those to change their
3629            // order except due to activity operations.
3630            return;
3631        }
3632
3633        mLruSeq++;
3634        final long now = SystemClock.uptimeMillis();
3635        app.lastActivityTime = now;
3636
3637        // First a quick reject: if the app is already at the position we will
3638        // put it, then there is nothing to do.
3639        if (hasActivity) {
3640            final int N = mLruProcesses.size();
3641            if (N > 0 && mLruProcesses.get(N-1) == app) {
3642                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3643                return;
3644            }
3645        } else {
3646            if (mLruProcessServiceStart > 0
3647                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3648                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3649                return;
3650            }
3651        }
3652
3653        int lrui = mLruProcesses.lastIndexOf(app);
3654
3655        if (app.persistent && lrui >= 0) {
3656            // We don't care about the position of persistent processes, as long as
3657            // they are in the list.
3658            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3659            return;
3660        }
3661
3662        /* In progress: compute new position first, so we can avoid doing work
3663           if the process is not actually going to move.  Not yet working.
3664        int addIndex;
3665        int nextIndex;
3666        boolean inActivity = false, inService = false;
3667        if (hasActivity) {
3668            // Process has activities, put it at the very tipsy-top.
3669            addIndex = mLruProcesses.size();
3670            nextIndex = mLruProcessServiceStart;
3671            inActivity = true;
3672        } else if (hasService) {
3673            // Process has services, put it at the top of the service list.
3674            addIndex = mLruProcessActivityStart;
3675            nextIndex = mLruProcessServiceStart;
3676            inActivity = true;
3677            inService = true;
3678        } else  {
3679            // Process not otherwise of interest, it goes to the top of the non-service area.
3680            addIndex = mLruProcessServiceStart;
3681            if (client != null) {
3682                int clientIndex = mLruProcesses.lastIndexOf(client);
3683                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3684                        + app);
3685                if (clientIndex >= 0 && addIndex > clientIndex) {
3686                    addIndex = clientIndex;
3687                }
3688            }
3689            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3690        }
3691
3692        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3693                + mLruProcessActivityStart + "): " + app);
3694        */
3695
3696        if (lrui >= 0) {
3697            if (lrui < mLruProcessActivityStart) {
3698                mLruProcessActivityStart--;
3699            }
3700            if (lrui < mLruProcessServiceStart) {
3701                mLruProcessServiceStart--;
3702            }
3703            /*
3704            if (addIndex > lrui) {
3705                addIndex--;
3706            }
3707            if (nextIndex > lrui) {
3708                nextIndex--;
3709            }
3710            */
3711            mLruProcesses.remove(lrui);
3712        }
3713
3714        /*
3715        mLruProcesses.add(addIndex, app);
3716        if (inActivity) {
3717            mLruProcessActivityStart++;
3718        }
3719        if (inService) {
3720            mLruProcessActivityStart++;
3721        }
3722        */
3723
3724        int nextIndex;
3725        if (hasActivity) {
3726            final int N = mLruProcesses.size();
3727            if ((app.activities.size() == 0 || app.recentTasks.size() > 0)
3728                    && mLruProcessActivityStart < (N - 1)) {
3729                // Process doesn't have activities, but has clients with
3730                // activities...  move it up, but one below the top (the top
3731                // should always have a real activity).
3732                if (DEBUG_LRU) Slog.d(TAG_LRU,
3733                        "Adding to second-top of LRU activity list: " + app);
3734                mLruProcesses.add(N - 1, app);
3735                // To keep it from spamming the LRU list (by making a bunch of clients),
3736                // we will push down any other entries owned by the app.
3737                final int uid = app.info.uid;
3738                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3739                    ProcessRecord subProc = mLruProcesses.get(i);
3740                    if (subProc.info.uid == uid) {
3741                        // We want to push this one down the list.  If the process after
3742                        // it is for the same uid, however, don't do so, because we don't
3743                        // want them internally to be re-ordered.
3744                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3745                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3746                                    "Pushing uid " + uid + " swapping at " + i + ": "
3747                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3748                            ProcessRecord tmp = mLruProcesses.get(i);
3749                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3750                            mLruProcesses.set(i - 1, tmp);
3751                            i--;
3752                        }
3753                    } else {
3754                        // A gap, we can stop here.
3755                        break;
3756                    }
3757                }
3758            } else {
3759                // Process has activities, put it at the very tipsy-top.
3760                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3761                mLruProcesses.add(app);
3762            }
3763            nextIndex = mLruProcessServiceStart;
3764        } else if (hasService) {
3765            // Process has services, put it at the top of the service list.
3766            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3767            mLruProcesses.add(mLruProcessActivityStart, app);
3768            nextIndex = mLruProcessServiceStart;
3769            mLruProcessActivityStart++;
3770        } else  {
3771            // Process not otherwise of interest, it goes to the top of the non-service area.
3772            int index = mLruProcessServiceStart;
3773            if (client != null) {
3774                // If there is a client, don't allow the process to be moved up higher
3775                // in the list than that client.
3776                int clientIndex = mLruProcesses.lastIndexOf(client);
3777                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3778                        + " when updating " + app);
3779                if (clientIndex <= lrui) {
3780                    // Don't allow the client index restriction to push it down farther in the
3781                    // list than it already is.
3782                    clientIndex = lrui;
3783                }
3784                if (clientIndex >= 0 && index > clientIndex) {
3785                    index = clientIndex;
3786                }
3787            }
3788            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3789            mLruProcesses.add(index, app);
3790            nextIndex = index-1;
3791            mLruProcessActivityStart++;
3792            mLruProcessServiceStart++;
3793        }
3794
3795        // If the app is currently using a content provider or service,
3796        // bump those processes as well.
3797        for (int j=app.connections.size()-1; j>=0; j--) {
3798            ConnectionRecord cr = app.connections.valueAt(j);
3799            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3800                    && cr.binding.service.app != null
3801                    && cr.binding.service.app.lruSeq != mLruSeq
3802                    && !cr.binding.service.app.persistent) {
3803                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3804                        "service connection", cr, app);
3805            }
3806        }
3807        for (int j=app.conProviders.size()-1; j>=0; j--) {
3808            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3809            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3810                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3811                        "provider reference", cpr, app);
3812            }
3813        }
3814    }
3815
3816    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3817        if (uid == SYSTEM_UID) {
3818            // The system gets to run in any process.  If there are multiple
3819            // processes with the same uid, just pick the first (this
3820            // should never happen).
3821            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3822            if (procs == null) return null;
3823            final int procCount = procs.size();
3824            for (int i = 0; i < procCount; i++) {
3825                final int procUid = procs.keyAt(i);
3826                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3827                    // Don't use an app process or different user process for system component.
3828                    continue;
3829                }
3830                return procs.valueAt(i);
3831            }
3832        }
3833        ProcessRecord proc = mProcessNames.get(processName, uid);
3834        if (false && proc != null && !keepIfLarge
3835                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3836                && proc.lastCachedPss >= 4000) {
3837            // Turn this condition on to cause killing to happen regularly, for testing.
3838            if (proc.baseProcessTracker != null) {
3839                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3840            }
3841            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3842        } else if (proc != null && !keepIfLarge
3843                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3844                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3845            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3846            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3847                if (proc.baseProcessTracker != null) {
3848                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3849                }
3850                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3851            }
3852        }
3853        return proc;
3854    }
3855
3856    void notifyPackageUse(String packageName, int reason) {
3857        synchronized(this) {
3858            getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3859        }
3860    }
3861
3862    boolean isNextTransitionForward() {
3863        int transit = mWindowManager.getPendingAppTransition();
3864        return transit == TRANSIT_ACTIVITY_OPEN
3865                || transit == TRANSIT_TASK_OPEN
3866                || transit == TRANSIT_TASK_TO_FRONT;
3867    }
3868
3869    boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3870            String processName, String abiOverride, int uid, Runnable crashHandler) {
3871        synchronized(this) {
3872            ApplicationInfo info = new ApplicationInfo();
3873            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3874            // For isolated processes, the former contains the parent's uid and the latter the
3875            // actual uid of the isolated process.
3876            // In the special case introduced by this method (which is, starting an isolated
3877            // process directly from the SystemServer without an actual parent app process) the
3878            // closest thing to a parent's uid is SYSTEM_UID.
3879            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3880            // the |isolated| logic in the ProcessRecord constructor.
3881            info.uid = SYSTEM_UID;
3882            info.processName = processName;
3883            info.className = entryPoint;
3884            info.packageName = "android";
3885            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3886            info.targetSdkVersion = Build.VERSION.SDK_INT;
3887            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3888                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3889                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3890                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3891                    crashHandler);
3892            return proc != null;
3893        }
3894    }
3895
3896    @GuardedBy("this")
3897    final ProcessRecord startProcessLocked(String processName,
3898            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3899            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3900            boolean isolated, boolean keepIfLarge) {
3901        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3902                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3903                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3904                null /* crashHandler */);
3905    }
3906
3907    @GuardedBy("this")
3908    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3909            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3910            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3911            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3912        long startTime = SystemClock.elapsedRealtime();
3913        ProcessRecord app;
3914        if (!isolated) {
3915            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3916            checkTime(startTime, "startProcess: after getProcessRecord");
3917
3918            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3919                // If we are in the background, then check to see if this process
3920                // is bad.  If so, we will just silently fail.
3921                if (mAppErrors.isBadProcessLocked(info)) {
3922                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3923                            + "/" + info.processName);
3924                    return null;
3925                }
3926            } else {
3927                // When the user is explicitly starting a process, then clear its
3928                // crash count so that we won't make it bad until they see at
3929                // least one crash dialog again, and make the process good again
3930                // if it had been bad.
3931                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3932                        + "/" + info.processName);
3933                mAppErrors.resetProcessCrashTimeLocked(info);
3934                if (mAppErrors.isBadProcessLocked(info)) {
3935                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3936                            UserHandle.getUserId(info.uid), info.uid,
3937                            info.processName);
3938                    mAppErrors.clearBadProcessLocked(info);
3939                    if (app != null) {
3940                        app.bad = false;
3941                    }
3942                }
3943            }
3944        } else {
3945            // If this is an isolated process, it can't re-use an existing process.
3946            app = null;
3947        }
3948
3949        // We don't have to do anything more if:
3950        // (1) There is an existing application record; and
3951        // (2) The caller doesn't think it is dead, OR there is no thread
3952        //     object attached to it so we know it couldn't have crashed; and
3953        // (3) There is a pid assigned to it, so it is either starting or
3954        //     already running.
3955        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3956                + " app=" + app + " knownToBeDead=" + knownToBeDead
3957                + " thread=" + (app != null ? app.thread : null)
3958                + " pid=" + (app != null ? app.pid : -1));
3959        if (app != null && app.pid > 0) {
3960            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3961                // We already have the app running, or are waiting for it to
3962                // come up (we have a pid but not yet its thread), so keep it.
3963                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3964                // If this is a new package in the process, add the package to the list
3965                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3966                checkTime(startTime, "startProcess: done, added package to proc");
3967                return app;
3968            }
3969
3970            // An application record is attached to a previous process,
3971            // clean it up now.
3972            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3973            checkTime(startTime, "startProcess: bad proc running, killing");
3974            killProcessGroup(app.uid, app.pid);
3975            handleAppDiedLocked(app, true, true);
3976            checkTime(startTime, "startProcess: done killing old proc");
3977        }
3978
3979        String hostingNameStr = hostingName != null
3980                ? hostingName.flattenToShortString() : null;
3981
3982        if (app == null) {
3983            checkTime(startTime, "startProcess: creating new process record");
3984            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3985            if (app == null) {
3986                Slog.w(TAG, "Failed making new process record for "
3987                        + processName + "/" + info.uid + " isolated=" + isolated);
3988                return null;
3989            }
3990            app.crashHandler = crashHandler;
3991            app.isolatedEntryPoint = entryPoint;
3992            app.isolatedEntryPointArgs = entryPointArgs;
3993            checkTime(startTime, "startProcess: done creating new process record");
3994        } else {
3995            // If this is a new package in the process, add the package to the list
3996            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3997            checkTime(startTime, "startProcess: added package to existing proc");
3998        }
3999
4000        // If the system is not ready yet, then hold off on starting this
4001        // process until it is.
4002        if (!mProcessesReady
4003                && !isAllowedWhileBooting(info)
4004                && !allowWhileBooting) {
4005            if (!mProcessesOnHold.contains(app)) {
4006                mProcessesOnHold.add(app);
4007            }
4008            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
4009                    "System not ready, putting on hold: " + app);
4010            checkTime(startTime, "startProcess: returning with proc on hold");
4011            return app;
4012        }
4013
4014        checkTime(startTime, "startProcess: stepping in to startProcess");
4015        final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
4016        checkTime(startTime, "startProcess: done starting proc!");
4017        return success ? app : null;
4018    }
4019
4020    boolean isAllowedWhileBooting(ApplicationInfo ai) {
4021        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
4022    }
4023
4024    @GuardedBy("this")
4025    private final void startProcessLocked(ProcessRecord app,
4026            String hostingType, String hostingNameStr) {
4027        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
4028    }
4029
4030    @GuardedBy("this")
4031    private final boolean startProcessLocked(ProcessRecord app,
4032            String hostingType, String hostingNameStr, String abiOverride) {
4033        return startProcessLocked(app, hostingType, hostingNameStr,
4034                false /* disableHiddenApiChecks */, abiOverride);
4035    }
4036
4037    /**
4038     * @return {@code true} if process start is successful, false otherwise.
4039     */
4040    @GuardedBy("this")
4041    private final boolean startProcessLocked(ProcessRecord app, String hostingType,
4042            String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
4043        if (app.pendingStart) {
4044            return true;
4045        }
4046        long startTime = SystemClock.elapsedRealtime();
4047        if (app.pid > 0 && app.pid != MY_PID) {
4048            checkTime(startTime, "startProcess: removing from pids map");
4049            synchronized (mPidsSelfLocked) {
4050                mPidsSelfLocked.remove(app.pid);
4051                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4052            }
4053            checkTime(startTime, "startProcess: done removing from pids map");
4054            app.setPid(0);
4055        }
4056
4057        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
4058                "startProcessLocked removing on hold: " + app);
4059        mProcessesOnHold.remove(app);
4060
4061        checkTime(startTime, "startProcess: starting to update cpu stats");
4062        updateCpuStats();
4063        checkTime(startTime, "startProcess: done updating cpu stats");
4064
4065        try {
4066            try {
4067                final int userId = UserHandle.getUserId(app.uid);
4068                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
4069            } catch (RemoteException e) {
4070                throw e.rethrowAsRuntimeException();
4071            }
4072
4073            int uid = app.uid;
4074            int[] gids = null;
4075            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
4076            if (!app.isolated) {
4077                int[] permGids = null;
4078                try {
4079                    checkTime(startTime, "startProcess: getting gids from package manager");
4080                    final IPackageManager pm = AppGlobals.getPackageManager();
4081                    permGids = pm.getPackageGids(app.info.packageName,
4082                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
4083                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
4084                            StorageManagerInternal.class);
4085                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
4086                            app.info.packageName);
4087                } catch (RemoteException e) {
4088                    throw e.rethrowAsRuntimeException();
4089                }
4090
4091                /*
4092                 * Add shared application and profile GIDs so applications can share some
4093                 * resources like shared libraries and access user-wide resources
4094                 */
4095                if (ArrayUtils.isEmpty(permGids)) {
4096                    gids = new int[3];
4097                } else {
4098                    gids = new int[permGids.length + 3];
4099                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
4100                }
4101                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
4102                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
4103                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
4104
4105                // Replace any invalid GIDs
4106                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
4107                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
4108            }
4109            checkTime(startTime, "startProcess: building args");
4110            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
4111                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4112                        && mTopComponent != null
4113                        && app.processName.equals(mTopComponent.getPackageName())) {
4114                    uid = 0;
4115                }
4116                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
4117                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
4118                    uid = 0;
4119                }
4120            }
4121            int runtimeFlags = 0;
4122            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4123                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
4124                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
4125                // Also turn on CheckJNI for debuggable apps. It's quite
4126                // awkward to turn on otherwise.
4127                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4128            }
4129            // Run the app in safe mode if its manifest requests so or the
4130            // system is booted in safe mode.
4131            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
4132                mSafeMode == true) {
4133                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
4134            }
4135            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
4136                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
4137            }
4138            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
4139            if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
4140                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
4141            }
4142            String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
4143            if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
4144                runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
4145            }
4146            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
4147                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
4148            }
4149            if ("1".equals(SystemProperties.get("debug.assert"))) {
4150                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
4151            }
4152            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
4153                // Enable all debug flags required by the native debugger.
4154                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
4155                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
4156                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
4157                mNativeDebuggingApp = null;
4158            }
4159
4160            if (app.info.isPrivilegedApp() &&
4161                    SystemProperties.getBoolean("pm.dexopt.priv-apps-oob", false)) {
4162                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
4163            }
4164
4165            if (!app.info.isAllowedToUseHiddenApi() &&
4166                    !disableHiddenApiChecks &&
4167                    !mHiddenApiBlacklist.isDisabled()) {
4168                // This app is not allowed to use undocumented and private APIs, or blacklisting is
4169                // enabled. Set up its runtime with the appropriate flag.
4170                runtimeFlags |= Zygote.ENABLE_HIDDEN_API_CHECKS;
4171            }
4172
4173            String invokeWith = null;
4174            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
4175                // Debuggable apps may include a wrapper script with their library directory.
4176                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
4177                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4178                try {
4179                    if (new File(wrapperFileName).exists()) {
4180                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
4181                    }
4182                } finally {
4183                    StrictMode.setThreadPolicy(oldPolicy);
4184                }
4185            }
4186
4187            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
4188            if (requiredAbi == null) {
4189                requiredAbi = Build.SUPPORTED_ABIS[0];
4190            }
4191
4192            String instructionSet = null;
4193            if (app.info.primaryCpuAbi != null) {
4194                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
4195            }
4196
4197            app.gids = gids;
4198            app.requiredAbi = requiredAbi;
4199            app.instructionSet = instructionSet;
4200
4201            // the per-user SELinux context must be set
4202            if (TextUtils.isEmpty(app.info.seInfoUser)) {
4203                Slog.wtf(TAG, "SELinux tag not defined",
4204                        new IllegalStateException("SELinux tag not defined for "
4205                        + app.info.packageName + " (uid " + app.uid + ")"));
4206            }
4207            final String seInfo = app.info.seInfo
4208                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
4209            // Start the process.  It will either succeed and return a result containing
4210            // the PID of the new process, or else throw a RuntimeException.
4211            final String entryPoint = "android.app.ActivityThread";
4212
4213            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
4214                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
4215                    startTime);
4216        } catch (RuntimeException e) {
4217            Slog.e(TAG, "Failure starting process " + app.processName, e);
4218
4219            // Something went very wrong while trying to start this process; one
4220            // common case is when the package is frozen due to an active
4221            // upgrade. To recover, clean up any active bookkeeping related to
4222            // starting this process. (We already invoked this method once when
4223            // the package was initially frozen through KILL_APPLICATION_MSG, so
4224            // it doesn't hurt to use it again.)
4225            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4226                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4227            return false;
4228        }
4229    }
4230
4231    @GuardedBy("this")
4232    private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
4233            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4234            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4235            long startTime) {
4236        app.pendingStart = true;
4237        app.killedByAm = false;
4238        app.removed = false;
4239        app.killed = false;
4240        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
4241        app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
4242        if (mConstants.FLAG_PROCESS_START_ASYNC) {
4243            if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
4244                    "Posting procStart msg for " + app.toShortString());
4245            mProcStartHandler.post(() -> {
4246                try {
4247                    synchronized (ActivityManagerService.this) {
4248                        final String reason = isProcStartValidLocked(app, startSeq);
4249                        if (reason != null) {
4250                            Slog.w(TAG_PROCESSES, app + " not valid anymore,"
4251                                    + " don't start process, " + reason);
4252                            app.pendingStart = false;
4253                            return;
4254                        }
4255                        app.usingWrapper = invokeWith != null
4256                                || SystemProperties.get("wrap." + app.processName) != null;
4257                        mPendingStarts.put(startSeq, app);
4258                    }
4259                    final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
4260                            app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
4261                            requiredAbi, instructionSet, invokeWith, app.startTime);
4262                    synchronized (ActivityManagerService.this) {
4263                        handleProcessStartedLocked(app, startResult, startSeq);
4264                    }
4265                } catch (RuntimeException e) {
4266                    synchronized (ActivityManagerService.this) {
4267                        Slog.e(TAG, "Failure starting process " + app.processName, e);
4268                        mPendingStarts.remove(startSeq);
4269                        app.pendingStart = false;
4270                        forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4271                                false, false, true, false, false,
4272                                UserHandle.getUserId(app.userId), "start failure");
4273                    }
4274                }
4275            });
4276            return true;
4277        } else {
4278            try {
4279                final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
4280                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
4281                        invokeWith, startTime);
4282                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
4283                        startSeq, false);
4284            } catch (RuntimeException e) {
4285                Slog.e(TAG, "Failure starting process " + app.processName, e);
4286                app.pendingStart = false;
4287                forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
4288                        false, false, true, false, false,
4289                        UserHandle.getUserId(app.userId), "start failure");
4290            }
4291            return app.pid > 0;
4292        }
4293    }
4294
4295    private ProcessStartResult startProcess(String hostingType, String entryPoint,
4296            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
4297            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
4298            long startTime) {
4299        try {
4300            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
4301                    app.processName);
4302            checkTime(startTime, "startProcess: asking zygote to start proc");
4303            final ProcessStartResult startResult;
4304            if (hostingType.equals("webview_service")) {
4305                startResult = startWebView(entryPoint,
4306                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4307                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4308                        app.info.dataDir, null,
4309                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4310            } else {
4311                startResult = Process.start(entryPoint,
4312                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
4313                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
4314                        app.info.dataDir, invokeWith,
4315                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
4316            }
4317            checkTime(startTime, "startProcess: returned from zygote!");
4318            return startResult;
4319        } finally {
4320            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4321        }
4322    }
4323
4324    @GuardedBy("this")
4325    private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
4326        StringBuilder sb = null;
4327        if (app.killedByAm) {
4328            if (sb == null) sb = new StringBuilder();
4329            sb.append("killedByAm=true;");
4330        }
4331        if (mProcessNames.get(app.processName, app.uid) != app) {
4332            if (sb == null) sb = new StringBuilder();
4333            sb.append("No entry in mProcessNames;");
4334        }
4335        if (!app.pendingStart) {
4336            if (sb == null) sb = new StringBuilder();
4337            sb.append("pendingStart=false;");
4338        }
4339        if (app.startSeq > expectedStartSeq) {
4340            if (sb == null) sb = new StringBuilder();
4341            sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
4342        }
4343        return sb == null ? null : sb.toString();
4344    }
4345
4346    @GuardedBy("this")
4347    private boolean handleProcessStartedLocked(ProcessRecord pending,
4348            ProcessStartResult startResult, long expectedStartSeq) {
4349        // Indicates that this process start has been taken care of.
4350        if (mPendingStarts.get(expectedStartSeq) == null) {
4351            if (pending.pid == startResult.pid) {
4352                pending.usingWrapper = startResult.usingWrapper;
4353                // TODO: Update already existing clients of usingWrapper
4354            }
4355            return false;
4356        }
4357        return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
4358                expectedStartSeq, false);
4359    }
4360
4361    @GuardedBy("this")
4362    private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
4363            long expectedStartSeq, boolean procAttached) {
4364        mPendingStarts.remove(expectedStartSeq);
4365        final String reason = isProcStartValidLocked(app, expectedStartSeq);
4366        if (reason != null) {
4367            Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
4368                    + ", " + reason);
4369            app.pendingStart = false;
4370            Process.killProcessQuiet(pid);
4371            Process.killProcessGroup(app.uid, app.pid);
4372            return false;
4373        }
4374        mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
4375        checkTime(app.startTime, "startProcess: done updating battery stats");
4376
4377        EventLog.writeEvent(EventLogTags.AM_PROC_START,
4378                UserHandle.getUserId(app.startUid), pid, app.startUid,
4379                app.processName, app.hostingType,
4380                app.hostingNameStr != null ? app.hostingNameStr : "");
4381
4382        try {
4383            AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
4384                    app.seInfo, app.info.sourceDir, pid);
4385        } catch (RemoteException ex) {
4386            // Ignore
4387        }
4388
4389        if (app.persistent) {
4390            Watchdog.getInstance().processStarted(app.processName, pid);
4391        }
4392
4393        checkTime(app.startTime, "startProcess: building log message");
4394        StringBuilder buf = mStringBuilder;
4395        buf.setLength(0);
4396        buf.append("Start proc ");
4397        buf.append(pid);
4398        buf.append(':');
4399        buf.append(app.processName);
4400        buf.append('/');
4401        UserHandle.formatUid(buf, app.startUid);
4402        if (app.isolatedEntryPoint != null) {
4403            buf.append(" [");
4404            buf.append(app.isolatedEntryPoint);
4405            buf.append("]");
4406        }
4407        buf.append(" for ");
4408        buf.append(app.hostingType);
4409        if (app.hostingNameStr != null) {
4410            buf.append(" ");
4411            buf.append(app.hostingNameStr);
4412        }
4413        Slog.i(TAG, buf.toString());
4414        app.setPid(pid);
4415        app.usingWrapper = usingWrapper;
4416        app.pendingStart = false;
4417        checkTime(app.startTime, "startProcess: starting to update pids map");
4418        ProcessRecord oldApp;
4419        synchronized (mPidsSelfLocked) {
4420            oldApp = mPidsSelfLocked.get(pid);
4421        }
4422        // If there is already an app occupying that pid that hasn't been cleaned up
4423        if (oldApp != null && !app.isolated) {
4424            // Clean up anything relating to this pid first
4425            Slog.w(TAG, "Reusing pid " + pid
4426                    + " while app is still mapped to it");
4427            cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4428                    true /*replacingPid*/);
4429        }
4430        synchronized (mPidsSelfLocked) {
4431            this.mPidsSelfLocked.put(pid, app);
4432            if (!procAttached) {
4433                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4434                msg.obj = app;
4435                mHandler.sendMessageDelayed(msg, usingWrapper
4436                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4437            }
4438        }
4439        checkTime(app.startTime, "startProcess: done updating pids map");
4440        return true;
4441    }
4442
4443    void updateUsageStats(ActivityRecord component, boolean resumed) {
4444        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4445                "updateUsageStats: comp=" + component + "res=" + resumed);
4446        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4447        StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
4448            component.app.uid, component.realActivity.getPackageName(),
4449            component.realActivity.getShortClassName(), resumed ?
4450                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__ACTIVITY__MOVE_TO_FOREGROUND :
4451                        StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__ACTIVITY__MOVE_TO_BACKGROUND);
4452        if (resumed) {
4453            if (mUsageStatsService != null) {
4454                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4455                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4456
4457            }
4458            synchronized (stats) {
4459                stats.noteActivityResumedLocked(component.app.uid);
4460            }
4461        } else {
4462            if (mUsageStatsService != null) {
4463                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4464                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4465            }
4466            synchronized (stats) {
4467                stats.noteActivityPausedLocked(component.app.uid);
4468            }
4469        }
4470    }
4471
4472    Intent getHomeIntent() {
4473        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4474        intent.setComponent(mTopComponent);
4475        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4476        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4477            intent.addCategory(Intent.CATEGORY_HOME);
4478        }
4479        return intent;
4480    }
4481
4482    boolean startHomeActivityLocked(int userId, String reason) {
4483        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4484                && mTopAction == null) {
4485            // We are running in factory test mode, but unable to find
4486            // the factory test app, so just sit around displaying the
4487            // error message and don't try to start anything.
4488            return false;
4489        }
4490        Intent intent = getHomeIntent();
4491        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4492        if (aInfo != null) {
4493            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4494            // Don't do this if the home app is currently being
4495            // instrumented.
4496            aInfo = new ActivityInfo(aInfo);
4497            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4498            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4499                    aInfo.applicationInfo.uid, true);
4500            if (app == null || app.instr == null) {
4501                intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
4502                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4503                // For ANR debugging to verify if the user activity is the one that actually
4504                // launched.
4505                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4506                mActivityStartController.startHomeActivity(intent, aInfo, myReason);
4507            }
4508        } else {
4509            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4510        }
4511
4512        return true;
4513    }
4514
4515    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4516        ActivityInfo ai = null;
4517        ComponentName comp = intent.getComponent();
4518        try {
4519            if (comp != null) {
4520                // Factory test.
4521                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4522            } else {
4523                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4524                        intent,
4525                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4526                        flags, userId);
4527
4528                if (info != null) {
4529                    ai = info.activityInfo;
4530                }
4531            }
4532        } catch (RemoteException e) {
4533            // ignore
4534        }
4535
4536        return ai;
4537    }
4538
4539    boolean getCheckedForSetup() {
4540        return mCheckedForSetup;
4541    }
4542
4543    void setCheckedForSetup(boolean checked) {
4544        mCheckedForSetup = checked;
4545    }
4546
4547    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4548        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4549    }
4550
4551    void enforceNotIsolatedCaller(String caller) {
4552        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4553            throw new SecurityException("Isolated process not allowed to call " + caller);
4554        }
4555    }
4556
4557    @Override
4558    public int getFrontActivityScreenCompatMode() {
4559        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4560        synchronized (this) {
4561            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4562        }
4563    }
4564
4565    @Override
4566    public void setFrontActivityScreenCompatMode(int mode) {
4567        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4568                "setFrontActivityScreenCompatMode");
4569        synchronized (this) {
4570            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4571        }
4572    }
4573
4574    @Override
4575    public int getPackageScreenCompatMode(String packageName) {
4576        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4577        synchronized (this) {
4578            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4579        }
4580    }
4581
4582    @Override
4583    public void setPackageScreenCompatMode(String packageName, int mode) {
4584        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4585                "setPackageScreenCompatMode");
4586        synchronized (this) {
4587            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4588        }
4589    }
4590
4591    @Override
4592    public boolean getPackageAskScreenCompat(String packageName) {
4593        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4594        synchronized (this) {
4595            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4596        }
4597    }
4598
4599    @Override
4600    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4601        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4602                "setPackageAskScreenCompat");
4603        synchronized (this) {
4604            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4605        }
4606    }
4607
4608    private boolean hasUsageStatsPermission(String callingPackage) {
4609        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4610                Binder.getCallingUid(), callingPackage);
4611        if (mode == AppOpsManager.MODE_DEFAULT) {
4612            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4613                    == PackageManager.PERMISSION_GRANTED;
4614        }
4615        return mode == AppOpsManager.MODE_ALLOWED;
4616    }
4617
4618    @Override
4619    public int getPackageProcessState(String packageName, String callingPackage) {
4620        if (!hasUsageStatsPermission(callingPackage)) {
4621            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4622                    "getPackageProcessState");
4623        }
4624
4625        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4626        synchronized (this) {
4627            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4628                final ProcessRecord proc = mLruProcesses.get(i);
4629                if (procState > proc.setProcState) {
4630                    if (proc.pkgList.containsKey(packageName) ||
4631                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4632                        procState = proc.setProcState;
4633                    }
4634                }
4635            }
4636        }
4637        return procState;
4638    }
4639
4640    @Override
4641    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4642            throws RemoteException {
4643        synchronized (this) {
4644            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4645            if (app == null) {
4646                throw new IllegalArgumentException("Unknown process: " + process);
4647            }
4648            if (app.thread == null) {
4649                throw new IllegalArgumentException("Process has no app thread");
4650            }
4651            if (app.trimMemoryLevel >= level) {
4652                throw new IllegalArgumentException(
4653                        "Unable to set a higher trim level than current level");
4654            }
4655            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4656                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4657                throw new IllegalArgumentException("Unable to set a background trim level "
4658                    + "on a foreground process");
4659            }
4660            app.thread.scheduleTrimMemory(level);
4661            app.trimMemoryLevel = level;
4662            return true;
4663        }
4664    }
4665
4666    private void dispatchProcessesChanged() {
4667        int N;
4668        synchronized (this) {
4669            N = mPendingProcessChanges.size();
4670            if (mActiveProcessChanges.length < N) {
4671                mActiveProcessChanges = new ProcessChangeItem[N];
4672            }
4673            mPendingProcessChanges.toArray(mActiveProcessChanges);
4674            mPendingProcessChanges.clear();
4675            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4676                    "*** Delivering " + N + " process changes");
4677        }
4678
4679        int i = mProcessObservers.beginBroadcast();
4680        while (i > 0) {
4681            i--;
4682            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4683            if (observer != null) {
4684                try {
4685                    for (int j=0; j<N; j++) {
4686                        ProcessChangeItem item = mActiveProcessChanges[j];
4687                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4688                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4689                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4690                                    + item.uid + ": " + item.foregroundActivities);
4691                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4692                                    item.foregroundActivities);
4693                        }
4694                    }
4695                } catch (RemoteException e) {
4696                }
4697            }
4698        }
4699        mProcessObservers.finishBroadcast();
4700
4701        synchronized (this) {
4702            for (int j=0; j<N; j++) {
4703                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4704            }
4705        }
4706    }
4707
4708    private void dispatchProcessDied(int pid, int uid) {
4709        int i = mProcessObservers.beginBroadcast();
4710        while (i > 0) {
4711            i--;
4712            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4713            if (observer != null) {
4714                try {
4715                    observer.onProcessDied(pid, uid);
4716                } catch (RemoteException e) {
4717                }
4718            }
4719        }
4720        mProcessObservers.finishBroadcast();
4721    }
4722
4723    @VisibleForTesting
4724    void dispatchUidsChanged() {
4725        int N;
4726        synchronized (this) {
4727            N = mPendingUidChanges.size();
4728            if (mActiveUidChanges.length < N) {
4729                mActiveUidChanges = new UidRecord.ChangeItem[N];
4730            }
4731            for (int i=0; i<N; i++) {
4732                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4733                mActiveUidChanges[i] = change;
4734                if (change.uidRecord != null) {
4735                    change.uidRecord.pendingChange = null;
4736                    change.uidRecord = null;
4737                }
4738            }
4739            mPendingUidChanges.clear();
4740            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4741                    "*** Delivering " + N + " uid changes");
4742        }
4743
4744        mUidChangeDispatchCount += N;
4745        int i = mUidObservers.beginBroadcast();
4746        while (i > 0) {
4747            i--;
4748            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4749                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4750        }
4751        mUidObservers.finishBroadcast();
4752
4753        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4754            for (int j = 0; j < N; ++j) {
4755                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4756                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4757                    mValidateUids.remove(item.uid);
4758                } else {
4759                    UidRecord validateUid = mValidateUids.get(item.uid);
4760                    if (validateUid == null) {
4761                        validateUid = new UidRecord(item.uid);
4762                        mValidateUids.put(item.uid, validateUid);
4763                    }
4764                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4765                        validateUid.idle = true;
4766                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4767                        validateUid.idle = false;
4768                    }
4769                    validateUid.curProcState = validateUid.setProcState = item.processState;
4770                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4771                }
4772            }
4773        }
4774
4775        synchronized (this) {
4776            for (int j = 0; j < N; j++) {
4777                mAvailUidChanges.add(mActiveUidChanges[j]);
4778            }
4779        }
4780    }
4781
4782    private void dispatchUidsChangedForObserver(IUidObserver observer,
4783            UidObserverRegistration reg, int changesSize) {
4784        if (observer == null) {
4785            return;
4786        }
4787        try {
4788            for (int j = 0; j < changesSize; j++) {
4789                UidRecord.ChangeItem item = mActiveUidChanges[j];
4790                final int change = item.change;
4791                if (change == UidRecord.CHANGE_PROCSTATE &&
4792                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4793                    // No-op common case: no significant change, the observer is not
4794                    // interested in all proc state changes.
4795                    continue;
4796                }
4797                final long start = SystemClock.uptimeMillis();
4798                if ((change & UidRecord.CHANGE_IDLE) != 0) {
4799                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4800                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4801                                "UID idle uid=" + item.uid);
4802                        observer.onUidIdle(item.uid, item.ephemeral);
4803                    }
4804                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4805                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4806                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4807                                "UID active uid=" + item.uid);
4808                        observer.onUidActive(item.uid);
4809                    }
4810                }
4811                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4812                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
4813                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4814                                "UID cached uid=" + item.uid);
4815                        observer.onUidCachedChanged(item.uid, true);
4816                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4817                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4818                                "UID active uid=" + item.uid);
4819                        observer.onUidCachedChanged(item.uid, false);
4820                    }
4821                }
4822                if ((change & UidRecord.CHANGE_GONE) != 0) {
4823                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4824                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4825                                "UID gone uid=" + item.uid);
4826                        observer.onUidGone(item.uid, item.ephemeral);
4827                    }
4828                    if (reg.lastProcStates != null) {
4829                        reg.lastProcStates.delete(item.uid);
4830                    }
4831                } else {
4832                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4833                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4834                                "UID CHANGED uid=" + item.uid
4835                                        + ": " + item.processState);
4836                        boolean doReport = true;
4837                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4838                            final int lastState = reg.lastProcStates.get(item.uid,
4839                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4840                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4841                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4842                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4843                                doReport = lastAboveCut != newAboveCut;
4844                            } else {
4845                                doReport = item.processState
4846                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4847                            }
4848                        }
4849                        if (doReport) {
4850                            if (reg.lastProcStates != null) {
4851                                reg.lastProcStates.put(item.uid, item.processState);
4852                            }
4853                            observer.onUidStateChanged(item.uid, item.processState,
4854                                    item.procStateSeq);
4855                        }
4856                    }
4857                }
4858                final int duration = (int) (SystemClock.uptimeMillis() - start);
4859                if (reg.mMaxDispatchTime < duration) {
4860                    reg.mMaxDispatchTime = duration;
4861                }
4862                if (duration >= SLOW_UID_OBSERVER_THRESHOLD_MS) {
4863                    reg.mSlowDispatchCount++;
4864                }
4865            }
4866        } catch (RemoteException e) {
4867        }
4868    }
4869
4870    void dispatchOomAdjObserver(String msg) {
4871        OomAdjObserver observer;
4872        synchronized (this) {
4873            observer = mCurOomAdjObserver;
4874        }
4875
4876        if (observer != null) {
4877            observer.onOomAdjMessage(msg);
4878        }
4879    }
4880
4881    void setOomAdjObserver(int uid, OomAdjObserver observer) {
4882        synchronized (this) {
4883            mCurOomAdjUid = uid;
4884            mCurOomAdjObserver = observer;
4885        }
4886    }
4887
4888    void clearOomAdjObserver() {
4889        synchronized (this) {
4890            mCurOomAdjUid = -1;
4891            mCurOomAdjObserver = null;
4892        }
4893    }
4894
4895    void reportOomAdjMessageLocked(String tag, String msg) {
4896        Slog.d(tag, msg);
4897        if (mCurOomAdjObserver != null) {
4898            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4899        }
4900    }
4901
4902    @Override
4903    public final int startActivity(IApplicationThread caller, String callingPackage,
4904            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4905            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4906        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4907                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4908                UserHandle.getCallingUserId());
4909    }
4910
4911    @Override
4912    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4913            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4914            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4915        enforceNotIsolatedCaller("startActivity");
4916        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4917                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4918        // TODO: Switch to user app stacks here.
4919        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
4920                .setCaller(caller)
4921                .setCallingPackage(callingPackage)
4922                .setResolvedType(resolvedType)
4923                .setResultTo(resultTo)
4924                .setResultWho(resultWho)
4925                .setRequestCode(requestCode)
4926                .setStartFlags(startFlags)
4927                .setProfilerInfo(profilerInfo)
4928                .setActivityOptions(bOptions)
4929                .setMayWait(userId)
4930                .execute();
4931
4932    }
4933
4934    @Override
4935    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4936            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4937            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4938            int userId) {
4939
4940        // This is very dangerous -- it allows you to perform a start activity (including
4941        // permission grants) as any app that may launch one of your own activities.  So
4942        // we will only allow this to be done from activities that are part of the core framework,
4943        // and then only when they are running as the system.
4944        final ActivityRecord sourceRecord;
4945        final int targetUid;
4946        final String targetPackage;
4947        synchronized (this) {
4948            if (resultTo == null) {
4949                throw new SecurityException("Must be called from an activity");
4950            }
4951            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4952            if (sourceRecord == null) {
4953                throw new SecurityException("Called with bad activity token: " + resultTo);
4954            }
4955            if (!sourceRecord.info.packageName.equals("android")) {
4956                throw new SecurityException(
4957                        "Must be called from an activity that is declared in the android package");
4958            }
4959            if (sourceRecord.app == null) {
4960                throw new SecurityException("Called without a process attached to activity");
4961            }
4962            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4963                // This is still okay, as long as this activity is running under the
4964                // uid of the original calling activity.
4965                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4966                    throw new SecurityException(
4967                            "Calling activity in uid " + sourceRecord.app.uid
4968                                    + " must be system uid or original calling uid "
4969                                    + sourceRecord.launchedFromUid);
4970                }
4971            }
4972            if (ignoreTargetSecurity) {
4973                if (intent.getComponent() == null) {
4974                    throw new SecurityException(
4975                            "Component must be specified with ignoreTargetSecurity");
4976                }
4977                if (intent.getSelector() != null) {
4978                    throw new SecurityException(
4979                            "Selector not allowed with ignoreTargetSecurity");
4980                }
4981            }
4982            targetUid = sourceRecord.launchedFromUid;
4983            targetPackage = sourceRecord.launchedFromPackage;
4984        }
4985
4986        if (userId == UserHandle.USER_NULL) {
4987            userId = UserHandle.getUserId(sourceRecord.app.uid);
4988        }
4989
4990        // TODO: Switch to user app stacks here.
4991        try {
4992            return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
4993                    .setCallingUid(targetUid)
4994                    .setCallingPackage(targetPackage)
4995                    .setResolvedType(resolvedType)
4996                    .setResultTo(resultTo)
4997                    .setResultWho(resultWho)
4998                    .setRequestCode(requestCode)
4999                    .setStartFlags(startFlags)
5000                    .setActivityOptions(bOptions)
5001                    .setMayWait(userId)
5002                    .setIgnoreTargetSecurity(ignoreTargetSecurity)
5003                    .execute();
5004        } catch (SecurityException e) {
5005            // XXX need to figure out how to propagate to original app.
5006            // A SecurityException here is generally actually a fault of the original
5007            // calling activity (such as a fairly granting permissions), so propagate it
5008            // back to them.
5009            /*
5010            StringBuilder msg = new StringBuilder();
5011            msg.append("While launching");
5012            msg.append(intent.toString());
5013            msg.append(": ");
5014            msg.append(e.getMessage());
5015            */
5016            throw e;
5017        }
5018    }
5019
5020    @Override
5021    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
5022            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5023            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
5024        enforceNotIsolatedCaller("startActivityAndWait");
5025        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5026                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
5027        WaitResult res = new WaitResult();
5028        // TODO: Switch to user app stacks here.
5029        mActivityStartController.obtainStarter(intent, "startActivityAndWait")
5030                .setCaller(caller)
5031                .setCallingPackage(callingPackage)
5032                .setResolvedType(resolvedType)
5033                .setResultTo(resultTo)
5034                .setResultWho(resultWho)
5035                .setRequestCode(requestCode)
5036                .setStartFlags(startFlags)
5037                .setActivityOptions(bOptions)
5038                .setMayWait(userId)
5039                .setProfilerInfo(profilerInfo)
5040                .setWaitResult(res)
5041                .execute();
5042        return res;
5043    }
5044
5045    @Override
5046    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
5047            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5048            int startFlags, Configuration config, Bundle bOptions, int userId) {
5049        enforceNotIsolatedCaller("startActivityWithConfig");
5050        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5051                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
5052        // TODO: Switch to user app stacks here.
5053        return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
5054                .setCaller(caller)
5055                .setCallingPackage(callingPackage)
5056                .setResolvedType(resolvedType)
5057                .setResultTo(resultTo)
5058                .setResultWho(resultWho)
5059                .setRequestCode(requestCode)
5060                .setStartFlags(startFlags)
5061                .setGlobalConfiguration(config)
5062                .setActivityOptions(bOptions)
5063                .setMayWait(userId)
5064                .execute();
5065    }
5066
5067    @Override
5068    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
5069            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
5070            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
5071            throws TransactionTooLargeException {
5072        enforceNotIsolatedCaller("startActivityIntentSender");
5073        // Refuse possible leaked file descriptors
5074        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
5075            throw new IllegalArgumentException("File descriptors passed in Intent");
5076        }
5077
5078        if (!(target instanceof PendingIntentRecord)) {
5079            throw new IllegalArgumentException("Bad PendingIntent object");
5080        }
5081
5082        PendingIntentRecord pir = (PendingIntentRecord)target;
5083
5084        synchronized (this) {
5085            // If this is coming from the currently resumed activity, it is
5086            // effectively saying that app switches are allowed at this point.
5087            final ActivityStack stack = getFocusedStack();
5088            if (stack.mResumedActivity != null &&
5089                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
5090                mAppSwitchesAllowedTime = 0;
5091            }
5092        }
5093        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
5094                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
5095        return ret;
5096    }
5097
5098    @Override
5099    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
5100            Intent intent, String resolvedType, IVoiceInteractionSession session,
5101            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
5102            Bundle bOptions, int userId) {
5103        enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
5104        if (session == null || interactor == null) {
5105            throw new NullPointerException("null session or interactor");
5106        }
5107        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5108                ALLOW_FULL_ONLY, "startVoiceActivity", null);
5109        // TODO: Switch to user app stacks here.
5110        return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
5111                .setCallingUid(callingUid)
5112                .setCallingPackage(callingPackage)
5113                .setResolvedType(resolvedType)
5114                .setVoiceSession(session)
5115                .setVoiceInteractor(interactor)
5116                .setStartFlags(startFlags)
5117                .setProfilerInfo(profilerInfo)
5118                .setActivityOptions(bOptions)
5119                .setMayWait(userId)
5120                .execute();
5121    }
5122
5123    @Override
5124    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
5125            Intent intent, String resolvedType, Bundle bOptions, int userId) {
5126        enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
5127        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
5128                ALLOW_FULL_ONLY, "startAssistantActivity", null);
5129
5130        return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
5131                .setCallingUid(callingUid)
5132                .setCallingPackage(callingPackage)
5133                .setResolvedType(resolvedType)
5134                .setActivityOptions(bOptions)
5135                .setMayWait(userId)
5136                .execute();
5137    }
5138
5139    @Override
5140    public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
5141                IRecentsAnimationRunner recentsAnimationRunner) {
5142        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
5143        final int callingPid = Binder.getCallingPid();
5144        final long origId = Binder.clearCallingIdentity();
5145        try {
5146            synchronized (this) {
5147                final int recentsUid = mRecentTasks.getRecentsComponentUid();
5148                final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
5149                final String recentsPackage = recentsComponent.getPackageName();
5150
5151                // If provided, kick off the request for the assist data in the background before
5152                // starting the activity
5153                if (assistDataReceiver != null) {
5154                    final AppOpsManager appOpsManager = (AppOpsManager)
5155                            mContext.getSystemService(Context.APP_OPS_SERVICE);
5156                    final AssistDataReceiverProxy proxy = new AssistDataReceiverProxy(
5157                            assistDataReceiver, recentsPackage);
5158                    final AssistDataRequester requester = new AssistDataRequester(mContext, this,
5159                            mWindowManager, appOpsManager, proxy, this,
5160                            OP_ASSIST_STRUCTURE, OP_NONE);
5161                    requester.requestAssistData(mStackSupervisor.getTopVisibleActivities(),
5162                            true /* fetchData */, false /* fetchScreenshots */,
5163                            true /* allowFetchData */, false /* alloweFetchScreenshots */,
5164                            recentsUid, recentsPackage);
5165                }
5166
5167                // Start a new recents animation
5168                final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
5169                        mActivityStartController, mWindowManager, mUserController, callingPid);
5170                anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
5171                        recentsUid);
5172            }
5173        } finally {
5174            Binder.restoreCallingIdentity(origId);
5175        }
5176    }
5177
5178    @Override
5179    public void cancelRecentsAnimation() {
5180        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
5181        final long origId = Binder.clearCallingIdentity();
5182        try {
5183            synchronized (this) {
5184                mWindowManager.cancelRecentsAnimation();
5185            }
5186        } finally {
5187            Binder.restoreCallingIdentity(origId);
5188        }
5189    }
5190
5191    @Override
5192    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
5193            throws RemoteException {
5194        Slog.i(TAG, "Activity tried to startVoiceInteraction");
5195        synchronized (this) {
5196            ActivityRecord activity = getFocusedStack().getTopActivity();
5197            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
5198                throw new SecurityException("Only focused activity can call startVoiceInteraction");
5199            }
5200            if (mRunningVoice != null || activity.getTask().voiceSession != null
5201                    || activity.voiceSession != null) {
5202                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
5203                return;
5204            }
5205            if (activity.pendingVoiceInteractionStart) {
5206                Slog.w(TAG, "Pending start of voice interaction already.");
5207                return;
5208            }
5209            activity.pendingVoiceInteractionStart = true;
5210        }
5211        LocalServices.getService(VoiceInteractionManagerInternal.class)
5212                .startLocalVoiceInteraction(callingActivity, options);
5213    }
5214
5215    @Override
5216    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
5217        LocalServices.getService(VoiceInteractionManagerInternal.class)
5218                .stopLocalVoiceInteraction(callingActivity);
5219    }
5220
5221    @Override
5222    public boolean supportsLocalVoiceInteraction() throws RemoteException {
5223        return LocalServices.getService(VoiceInteractionManagerInternal.class)
5224                .supportsLocalVoiceInteraction();
5225    }
5226
5227    @GuardedBy("this")
5228    void onLocalVoiceInteractionStartedLocked(IBinder activity,
5229            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
5230        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
5231        if (activityToCallback == null) return;
5232        activityToCallback.setVoiceSessionLocked(voiceSession);
5233
5234        // Inform the activity
5235        try {
5236            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
5237                    voiceInteractor);
5238            long token = Binder.clearCallingIdentity();
5239            try {
5240                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
5241            } finally {
5242                Binder.restoreCallingIdentity(token);
5243            }
5244            // TODO: VI Should we cache the activity so that it's easier to find later
5245            // rather than scan through all the stacks and activities?
5246        } catch (RemoteException re) {
5247            activityToCallback.clearVoiceSessionLocked();
5248            // TODO: VI Should this terminate the voice session?
5249        }
5250    }
5251
5252    @Override
5253    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
5254        synchronized (this) {
5255            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
5256                if (keepAwake) {
5257                    mVoiceWakeLock.acquire();
5258                } else {
5259                    mVoiceWakeLock.release();
5260                }
5261            }
5262        }
5263    }
5264
5265    @Override
5266    public boolean startNextMatchingActivity(IBinder callingActivity,
5267            Intent intent, Bundle bOptions) {
5268        // Refuse possible leaked file descriptors
5269        if (intent != null && intent.hasFileDescriptors() == true) {
5270            throw new IllegalArgumentException("File descriptors passed in Intent");
5271        }
5272        SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
5273
5274        synchronized (this) {
5275            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
5276            if (r == null) {
5277                SafeActivityOptions.abort(options);
5278                return false;
5279            }
5280            if (r.app == null || r.app.thread == null) {
5281                // The caller is not running...  d'oh!
5282                SafeActivityOptions.abort(options);
5283                return false;
5284            }
5285            intent = new Intent(intent);
5286            // The caller is not allowed to change the data.
5287            intent.setDataAndType(r.intent.getData(), r.intent.getType());
5288            // And we are resetting to find the next component...
5289            intent.setComponent(null);
5290
5291            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5292
5293            ActivityInfo aInfo = null;
5294            try {
5295                List<ResolveInfo> resolves =
5296                    AppGlobals.getPackageManager().queryIntentActivities(
5297                            intent, r.resolvedType,
5298                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
5299                            UserHandle.getCallingUserId()).getList();
5300
5301                // Look for the original activity in the list...
5302                final int N = resolves != null ? resolves.size() : 0;
5303                for (int i=0; i<N; i++) {
5304                    ResolveInfo rInfo = resolves.get(i);
5305                    if (rInfo.activityInfo.packageName.equals(r.packageName)
5306                            && rInfo.activityInfo.name.equals(r.info.name)) {
5307                        // We found the current one...  the next matching is
5308                        // after it.
5309                        i++;
5310                        if (i<N) {
5311                            aInfo = resolves.get(i).activityInfo;
5312                        }
5313                        if (debug) {
5314                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
5315                                    + "/" + r.info.name);
5316                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
5317                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
5318                        }
5319                        break;
5320                    }
5321                }
5322            } catch (RemoteException e) {
5323            }
5324
5325            if (aInfo == null) {
5326                // Nobody who is next!
5327                SafeActivityOptions.abort(options);
5328                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
5329                return false;
5330            }
5331
5332            intent.setComponent(new ComponentName(
5333                    aInfo.applicationInfo.packageName, aInfo.name));
5334            intent.setFlags(intent.getFlags()&~(
5335                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
5336                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
5337                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
5338                    FLAG_ACTIVITY_NEW_TASK));
5339
5340            // Okay now we need to start the new activity, replacing the
5341            // currently running activity.  This is a little tricky because
5342            // we want to start the new one as if the current one is finished,
5343            // but not finish the current one first so that there is no flicker.
5344            // And thus...
5345            final boolean wasFinishing = r.finishing;
5346            r.finishing = true;
5347
5348            // Propagate reply information over to the new activity.
5349            final ActivityRecord resultTo = r.resultTo;
5350            final String resultWho = r.resultWho;
5351            final int requestCode = r.requestCode;
5352            r.resultTo = null;
5353            if (resultTo != null) {
5354                resultTo.removeResultsLocked(r, resultWho, requestCode);
5355            }
5356
5357            final long origId = Binder.clearCallingIdentity();
5358            // TODO(b/64750076): Check if calling pid should really be -1.
5359            final int res = mActivityStartController
5360                    .obtainStarter(intent, "startNextMatchingActivity")
5361                    .setCaller(r.app.thread)
5362                    .setResolvedType(r.resolvedType)
5363                    .setActivityInfo(aInfo)
5364                    .setResultTo(resultTo != null ? resultTo.appToken : null)
5365                    .setResultWho(resultWho)
5366                    .setRequestCode(requestCode)
5367                    .setCallingPid(-1)
5368                    .setCallingUid(r.launchedFromUid)
5369                    .setCallingPackage(r.launchedFromPackage)
5370                    .setRealCallingPid(-1)
5371                    .setRealCallingUid(r.launchedFromUid)
5372                    .setActivityOptions(options)
5373                    .execute();
5374            Binder.restoreCallingIdentity(origId);
5375
5376            r.finishing = wasFinishing;
5377            if (res != ActivityManager.START_SUCCESS) {
5378                return false;
5379            }
5380            return true;
5381        }
5382    }
5383
5384    @Override
5385    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
5386        enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
5387                "startActivityFromRecents()");
5388
5389        final int callingPid = Binder.getCallingPid();
5390        final int callingUid = Binder.getCallingUid();
5391        final long origId = Binder.clearCallingIdentity();
5392        try {
5393            synchronized (this) {
5394                return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
5395                        SafeActivityOptions.fromBundle(bOptions));
5396            }
5397        } finally {
5398            Binder.restoreCallingIdentity(origId);
5399        }
5400    }
5401
5402    @Override
5403    public final int startActivities(IApplicationThread caller, String callingPackage,
5404            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
5405            int userId) {
5406        final String reason = "startActivities";
5407        enforceNotIsolatedCaller(reason);
5408        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5409                userId, false, ALLOW_FULL_ONLY, reason, null);
5410        // TODO: Switch to user app stacks here.
5411        int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
5412                intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
5413                reason);
5414        return ret;
5415    }
5416
5417    @Override
5418    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
5419        synchronized (this) {
5420            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5421            if (r == null) {
5422                return;
5423            }
5424            r.reportFullyDrawnLocked(restoredFromBundle);
5425        }
5426    }
5427
5428    @Override
5429    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
5430        synchronized (this) {
5431            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5432            if (r == null) {
5433                return;
5434            }
5435            final long origId = Binder.clearCallingIdentity();
5436            try {
5437                r.setRequestedOrientation(requestedOrientation);
5438            } finally {
5439                Binder.restoreCallingIdentity(origId);
5440            }
5441        }
5442    }
5443
5444    @Override
5445    public int getRequestedOrientation(IBinder token) {
5446        synchronized (this) {
5447            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5448            if (r == null) {
5449                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5450            }
5451            return r.getRequestedOrientation();
5452        }
5453    }
5454
5455    @Override
5456    public final void requestActivityRelaunch(IBinder token) {
5457        synchronized(this) {
5458            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5459            if (r == null) {
5460                return;
5461            }
5462            final long origId = Binder.clearCallingIdentity();
5463            try {
5464                r.forceNewConfig = true;
5465                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5466                        true /* preserveWindow */);
5467            } finally {
5468                Binder.restoreCallingIdentity(origId);
5469            }
5470        }
5471    }
5472
5473    /**
5474     * This is the internal entry point for handling Activity.finish().
5475     *
5476     * @param token The Binder token referencing the Activity we want to finish.
5477     * @param resultCode Result code, if any, from this Activity.
5478     * @param resultData Result data (Intent), if any, from this Activity.
5479     * @param finishTask Whether to finish the task associated with this Activity.
5480     *
5481     * @return Returns true if the activity successfully finished, or false if it is still running.
5482     */
5483    @Override
5484    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5485            int finishTask) {
5486        // Refuse possible leaked file descriptors
5487        if (resultData != null && resultData.hasFileDescriptors() == true) {
5488            throw new IllegalArgumentException("File descriptors passed in Intent");
5489        }
5490
5491        synchronized(this) {
5492            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5493            if (r == null) {
5494                return true;
5495            }
5496            // Keep track of the root activity of the task before we finish it
5497            TaskRecord tr = r.getTask();
5498            ActivityRecord rootR = tr.getRootActivity();
5499            if (rootR == null) {
5500                Slog.w(TAG, "Finishing task with all activities already finished");
5501            }
5502            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5503            // finish.
5504            if (mLockTaskController.activityBlockedFromFinish(r)) {
5505                return false;
5506            }
5507
5508            if (mController != null) {
5509                // Find the first activity that is not finishing.
5510                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5511                if (next != null) {
5512                    // ask watcher if this is allowed
5513                    boolean resumeOK = true;
5514                    try {
5515                        resumeOK = mController.activityResuming(next.packageName);
5516                    } catch (RemoteException e) {
5517                        mController = null;
5518                        Watchdog.getInstance().setActivityController(null);
5519                    }
5520
5521                    if (!resumeOK) {
5522                        Slog.i(TAG, "Not finishing activity because controller resumed");
5523                        return false;
5524                    }
5525                }
5526            }
5527            final long origId = Binder.clearCallingIdentity();
5528            try {
5529                boolean res;
5530                final boolean finishWithRootActivity =
5531                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5532                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5533                        || (finishWithRootActivity && r == rootR)) {
5534                    // If requested, remove the task that is associated to this activity only if it
5535                    // was the root activity in the task. The result code and data is ignored
5536                    // because we don't support returning them across task boundaries. Also, to
5537                    // keep backwards compatibility we remove the task from recents when finishing
5538                    // task with root activity.
5539                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5540                            finishWithRootActivity, "finish-activity");
5541                    if (!res) {
5542                        Slog.i(TAG, "Removing task failed to finish activity");
5543                    }
5544                } else {
5545                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5546                            resultData, "app-request", true);
5547                    if (!res) {
5548                        Slog.i(TAG, "Failed to finish by app-request");
5549                    }
5550                }
5551                return res;
5552            } finally {
5553                Binder.restoreCallingIdentity(origId);
5554            }
5555        }
5556    }
5557
5558    @Override
5559    public final void finishHeavyWeightApp() {
5560        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5561                != PackageManager.PERMISSION_GRANTED) {
5562            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5563                    + Binder.getCallingPid()
5564                    + ", uid=" + Binder.getCallingUid()
5565                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5566            Slog.w(TAG, msg);
5567            throw new SecurityException(msg);
5568        }
5569
5570        synchronized(this) {
5571            final ProcessRecord proc = mHeavyWeightProcess;
5572            if (proc == null) {
5573                return;
5574            }
5575
5576            ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities);
5577            for (int i = 0; i < activities.size(); i++) {
5578                ActivityRecord r = activities.get(i);
5579                if (!r.finishing && r.isInStackLocked()) {
5580                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5581                            null, "finish-heavy", true);
5582                }
5583            }
5584
5585            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5586                    proc.userId, 0));
5587            mHeavyWeightProcess = null;
5588        }
5589    }
5590
5591    @Override
5592    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5593            String message) {
5594        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5595                != PackageManager.PERMISSION_GRANTED) {
5596            String msg = "Permission Denial: crashApplication() from pid="
5597                    + Binder.getCallingPid()
5598                    + ", uid=" + Binder.getCallingUid()
5599                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5600            Slog.w(TAG, msg);
5601            throw new SecurityException(msg);
5602        }
5603
5604        synchronized(this) {
5605            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5606        }
5607    }
5608
5609    @Override
5610    public final void finishSubActivity(IBinder token, String resultWho,
5611            int requestCode) {
5612        synchronized(this) {
5613            final long origId = Binder.clearCallingIdentity();
5614            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5615            if (r != null) {
5616                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5617            }
5618            Binder.restoreCallingIdentity(origId);
5619        }
5620    }
5621
5622    @Override
5623    public boolean finishActivityAffinity(IBinder token) {
5624        synchronized(this) {
5625            final long origId = Binder.clearCallingIdentity();
5626            try {
5627                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5628                if (r == null) {
5629                    return false;
5630                }
5631
5632                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5633                // can finish.
5634                final TaskRecord task = r.getTask();
5635                if (mLockTaskController.activityBlockedFromFinish(r)) {
5636                    return false;
5637                }
5638                return task.getStack().finishActivityAffinityLocked(r);
5639            } finally {
5640                Binder.restoreCallingIdentity(origId);
5641            }
5642        }
5643    }
5644
5645    @Override
5646    public void finishVoiceTask(IVoiceInteractionSession session) {
5647        synchronized (this) {
5648            final long origId = Binder.clearCallingIdentity();
5649            try {
5650                // TODO: VI Consider treating local voice interactions and voice tasks
5651                // differently here
5652                mStackSupervisor.finishVoiceTask(session);
5653            } finally {
5654                Binder.restoreCallingIdentity(origId);
5655            }
5656        }
5657
5658    }
5659
5660    @Override
5661    public boolean releaseActivityInstance(IBinder token) {
5662        synchronized(this) {
5663            final long origId = Binder.clearCallingIdentity();
5664            try {
5665                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5666                if (r == null) {
5667                    return false;
5668                }
5669                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5670            } finally {
5671                Binder.restoreCallingIdentity(origId);
5672            }
5673        }
5674    }
5675
5676    @Override
5677    public void releaseSomeActivities(IApplicationThread appInt) {
5678        synchronized(this) {
5679            final long origId = Binder.clearCallingIdentity();
5680            try {
5681                ProcessRecord app = getRecordForAppLocked(appInt);
5682                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5683            } finally {
5684                Binder.restoreCallingIdentity(origId);
5685            }
5686        }
5687    }
5688
5689    @Override
5690    public boolean willActivityBeVisible(IBinder token) {
5691        synchronized(this) {
5692            ActivityStack stack = ActivityRecord.getStackLocked(token);
5693            if (stack != null) {
5694                return stack.willActivityBeVisibleLocked(token);
5695            }
5696            return false;
5697        }
5698    }
5699
5700    @Override
5701    public void overridePendingTransition(IBinder token, String packageName,
5702            int enterAnim, int exitAnim) {
5703        synchronized(this) {
5704            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5705            if (self == null) {
5706                return;
5707            }
5708
5709            final long origId = Binder.clearCallingIdentity();
5710
5711            if (self.state == ActivityState.RESUMED
5712                    || self.state == ActivityState.PAUSING) {
5713                mWindowManager.overridePendingAppTransition(packageName,
5714                        enterAnim, exitAnim, null);
5715            }
5716
5717            Binder.restoreCallingIdentity(origId);
5718        }
5719    }
5720
5721    /**
5722     * Main function for removing an existing process from the activity manager
5723     * as a result of that process going away.  Clears out all connections
5724     * to the process.
5725     */
5726    @GuardedBy("this")
5727    private final void handleAppDiedLocked(ProcessRecord app,
5728            boolean restarting, boolean allowRestart) {
5729        int pid = app.pid;
5730        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5731                false /*replacingPid*/);
5732        if (!kept && !restarting) {
5733            removeLruProcessLocked(app);
5734            if (pid > 0) {
5735                ProcessList.remove(pid);
5736            }
5737        }
5738
5739        if (mProfileProc == app) {
5740            clearProfilerLocked();
5741        }
5742
5743        // Remove this application's activities from active lists.
5744        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5745
5746        app.clearRecentTasks();
5747
5748        app.activities.clear();
5749
5750        if (app.instr != null) {
5751            Slog.w(TAG, "Crash of app " + app.processName
5752                  + " running instrumentation " + app.instr.mClass);
5753            Bundle info = new Bundle();
5754            info.putString("shortMsg", "Process crashed.");
5755            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5756        }
5757
5758        mWindowManager.deferSurfaceLayout();
5759        try {
5760            if (!restarting && hasVisibleActivities
5761                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5762                // If there was nothing to resume, and we are not already restarting this process, but
5763                // there is a visible activity that is hosted by the process...  then make sure all
5764                // visible activities are running, taking care of restarting this process.
5765                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5766            }
5767        } finally {
5768            mWindowManager.continueSurfaceLayout();
5769        }
5770    }
5771
5772    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5773        final IBinder threadBinder = thread.asBinder();
5774        // Find the application record.
5775        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5776            final ProcessRecord rec = mLruProcesses.get(i);
5777            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5778                return i;
5779            }
5780        }
5781        return -1;
5782    }
5783
5784    ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
5785        if (thread == null) {
5786            return null;
5787        }
5788
5789        int appIndex = getLRURecordIndexForAppLocked(thread);
5790        if (appIndex >= 0) {
5791            return mLruProcesses.get(appIndex);
5792        }
5793
5794        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5795        // double-check that.
5796        final IBinder threadBinder = thread.asBinder();
5797        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5798        for (int i = pmap.size()-1; i >= 0; i--) {
5799            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5800            for (int j = procs.size()-1; j >= 0; j--) {
5801                final ProcessRecord proc = procs.valueAt(j);
5802                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5803                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5804                            + proc);
5805                    return proc;
5806                }
5807            }
5808        }
5809
5810        return null;
5811    }
5812
5813    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5814        // If there are no longer any background processes running,
5815        // and the app that died was not running instrumentation,
5816        // then tell everyone we are now low on memory.
5817        boolean haveBg = false;
5818        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5819            ProcessRecord rec = mLruProcesses.get(i);
5820            if (rec.thread != null
5821                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5822                haveBg = true;
5823                break;
5824            }
5825        }
5826
5827        if (!haveBg) {
5828            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5829            if (doReport) {
5830                long now = SystemClock.uptimeMillis();
5831                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5832                    doReport = false;
5833                } else {
5834                    mLastMemUsageReportTime = now;
5835                }
5836            }
5837            final ArrayList<ProcessMemInfo> memInfos
5838                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5839            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5840            long now = SystemClock.uptimeMillis();
5841            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5842                ProcessRecord rec = mLruProcesses.get(i);
5843                if (rec == dyingProc || rec.thread == null) {
5844                    continue;
5845                }
5846                if (doReport) {
5847                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5848                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5849                }
5850                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5851                    // The low memory report is overriding any current
5852                    // state for a GC request.  Make sure to do
5853                    // heavy/important/visible/foreground processes first.
5854                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5855                        rec.lastRequestedGc = 0;
5856                    } else {
5857                        rec.lastRequestedGc = rec.lastLowMemory;
5858                    }
5859                    rec.reportLowMemory = true;
5860                    rec.lastLowMemory = now;
5861                    mProcessesToGc.remove(rec);
5862                    addProcessToGcListLocked(rec);
5863                }
5864            }
5865            if (doReport) {
5866                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5867                mHandler.sendMessage(msg);
5868            }
5869            scheduleAppGcsLocked();
5870        }
5871    }
5872
5873    @GuardedBy("this")
5874    final void appDiedLocked(ProcessRecord app) {
5875       appDiedLocked(app, app.pid, app.thread, false);
5876    }
5877
5878    @GuardedBy("this")
5879    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5880            boolean fromBinderDied) {
5881        // First check if this ProcessRecord is actually active for the pid.
5882        synchronized (mPidsSelfLocked) {
5883            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5884            if (curProc != app) {
5885                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5886                return;
5887            }
5888        }
5889
5890        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5891        synchronized (stats) {
5892            stats.noteProcessDiedLocked(app.info.uid, pid);
5893        }
5894
5895        if (!app.killed) {
5896            if (!fromBinderDied) {
5897                killProcessQuiet(pid);
5898            }
5899            killProcessGroup(app.uid, pid);
5900            app.killed = true;
5901        }
5902
5903        // Clean up already done if the process has been re-started.
5904        if (app.pid == pid && app.thread != null &&
5905                app.thread.asBinder() == thread.asBinder()) {
5906            boolean doLowMem = app.instr == null;
5907            boolean doOomAdj = doLowMem;
5908            if (!app.killedByAm) {
5909                Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5910                        + ProcessList.makeOomAdjString(app.setAdj)
5911                        + ProcessList.makeProcStateString(app.setProcState));
5912                mAllowLowerMemLevel = true;
5913            } else {
5914                // Note that we always want to do oom adj to update our state with the
5915                // new number of procs.
5916                mAllowLowerMemLevel = false;
5917                doLowMem = false;
5918            }
5919            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5920                    app.setAdj, app.setProcState);
5921            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5922                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5923            handleAppDiedLocked(app, false, true);
5924
5925            if (doOomAdj) {
5926                updateOomAdjLocked();
5927            }
5928            if (doLowMem) {
5929                doLowMemReportIfNeededLocked(app);
5930            }
5931        } else if (app.pid != pid) {
5932            // A new process has already been started.
5933            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5934                    + ") has died and restarted (pid " + app.pid + ").");
5935            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5936        } else if (DEBUG_PROCESSES) {
5937            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5938                    + thread.asBinder());
5939        }
5940    }
5941
5942    /**
5943     * If a stack trace dump file is configured, dump process stack traces.
5944     * @param clearTraces causes the dump file to be erased prior to the new
5945     *    traces being written, if true; when false, the new traces will be
5946     *    appended to any existing file content.
5947     * @param firstPids of dalvik VM processes to dump stack traces for first
5948     * @param lastPids of dalvik VM processes to dump stack traces for last
5949     * @param nativePids optional list of native pids to dump stack crawls
5950     */
5951    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5952            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5953            ArrayList<Integer> nativePids) {
5954        ArrayList<Integer> extraPids = null;
5955
5956        // Measure CPU usage as soon as we're called in order to get a realistic sampling
5957        // of the top users at the time of the request.
5958        if (processCpuTracker != null) {
5959            processCpuTracker.init();
5960            try {
5961                Thread.sleep(200);
5962            } catch (InterruptedException ignored) {
5963            }
5964
5965            processCpuTracker.update();
5966
5967            // We'll take the stack crawls of just the top apps using CPU.
5968            final int N = processCpuTracker.countWorkingStats();
5969            extraPids = new ArrayList<>();
5970            for (int i = 0; i < N && extraPids.size() < 5; i++) {
5971                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5972                if (lastPids.indexOfKey(stats.pid) >= 0) {
5973                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5974
5975                    extraPids.add(stats.pid);
5976                } else if (DEBUG_ANR) {
5977                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5978                            + stats.pid);
5979                }
5980            }
5981        }
5982
5983        boolean useTombstonedForJavaTraces = false;
5984        File tracesFile;
5985
5986        final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5987        if (tracesDirProp.isEmpty()) {
5988            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5989            // dumping scheme. All traces are written to a global trace file (usually
5990            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5991            // the file if requested.
5992            //
5993            // This mode of operation will be removed in the near future.
5994
5995
5996            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5997            if (globalTracesPath.isEmpty()) {
5998                Slog.w(TAG, "dumpStackTraces: no trace path configured");
5999                return null;
6000            }
6001
6002            tracesFile = new File(globalTracesPath);
6003            try {
6004                if (clearTraces && tracesFile.exists()) {
6005                    tracesFile.delete();
6006                }
6007
6008                tracesFile.createNewFile();
6009                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
6010            } catch (IOException e) {
6011                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
6012                return null;
6013            }
6014        } else {
6015            File tracesDir = new File(tracesDirProp);
6016            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
6017            // Each set of ANR traces is written to a separate file and dumpstate will process
6018            // all such files and add them to a captured bug report if they're recent enough.
6019            maybePruneOldTraces(tracesDir);
6020
6021            // NOTE: We should consider creating the file in native code atomically once we've
6022            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
6023            // can be removed.
6024            tracesFile = createAnrDumpFile(tracesDir);
6025            if (tracesFile == null) {
6026                return null;
6027            }
6028
6029            useTombstonedForJavaTraces = true;
6030        }
6031
6032        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
6033                useTombstonedForJavaTraces);
6034        return tracesFile;
6035    }
6036
6037    @GuardedBy("ActivityManagerService.class")
6038    private static SimpleDateFormat sAnrFileDateFormat;
6039
6040    private static synchronized File createAnrDumpFile(File tracesDir) {
6041        if (sAnrFileDateFormat == null) {
6042            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
6043        }
6044
6045        final String formattedDate = sAnrFileDateFormat.format(new Date());
6046        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
6047
6048        try {
6049            if (anrFile.createNewFile()) {
6050                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
6051                return anrFile;
6052            } else {
6053                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
6054            }
6055        } catch (IOException ioe) {
6056            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
6057        }
6058
6059        return null;
6060    }
6061
6062    /**
6063     * Prune all trace files that are more than a day old.
6064     *
6065     * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
6066     * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
6067     * since it's the system_server that creates trace files for most ANRs.
6068     */
6069    private static void maybePruneOldTraces(File tracesDir) {
6070        final long now = System.currentTimeMillis();
6071        final File[] traceFiles = tracesDir.listFiles();
6072
6073        if (traceFiles != null) {
6074            for (File file : traceFiles) {
6075                if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
6076                    if (!file.delete()) {
6077                        Slog.w(TAG, "Unable to prune stale trace file: " + file);
6078                    }
6079                }
6080            }
6081        }
6082    }
6083
6084    /**
6085     * Legacy code, do not use. Existing users will be deleted.
6086     *
6087     * @deprecated
6088     */
6089    @Deprecated
6090    public static class DumpStackFileObserver extends FileObserver {
6091        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
6092        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
6093
6094        private final String mTracesPath;
6095        private boolean mClosed;
6096
6097        public DumpStackFileObserver(String tracesPath) {
6098            super(tracesPath, FileObserver.CLOSE_WRITE);
6099            mTracesPath = tracesPath;
6100        }
6101
6102        @Override
6103        public synchronized void onEvent(int event, String path) {
6104            mClosed = true;
6105            notify();
6106        }
6107
6108        public long dumpWithTimeout(int pid, long timeout) {
6109            sendSignal(pid, SIGNAL_QUIT);
6110            final long start = SystemClock.elapsedRealtime();
6111
6112            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
6113            synchronized (this) {
6114                try {
6115                    wait(waitTime); // Wait for traces file to be closed.
6116                } catch (InterruptedException e) {
6117                    Slog.wtf(TAG, e);
6118                }
6119            }
6120
6121            // This avoids a corner case of passing a negative time to the native
6122            // trace in case we've already hit the overall timeout.
6123            final long timeWaited = SystemClock.elapsedRealtime() - start;
6124            if (timeWaited >= timeout) {
6125                return timeWaited;
6126            }
6127
6128            if (!mClosed) {
6129                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
6130                       ". Attempting native stack collection.");
6131
6132                final long nativeDumpTimeoutMs = Math.min(
6133                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
6134
6135                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
6136                        (int) (nativeDumpTimeoutMs / 1000));
6137            }
6138
6139            final long end = SystemClock.elapsedRealtime();
6140            mClosed = false;
6141
6142            return (end - start);
6143        }
6144    }
6145
6146    /**
6147     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
6148     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
6149     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
6150     * attempting to obtain native traces in the case of a failure. Returns the total time spent
6151     * capturing traces.
6152     */
6153    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
6154        final long timeStart = SystemClock.elapsedRealtime();
6155        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
6156            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
6157                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
6158        }
6159
6160        return SystemClock.elapsedRealtime() - timeStart;
6161    }
6162
6163    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
6164            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
6165            boolean useTombstonedForJavaTraces) {
6166
6167        // We don't need any sort of inotify based monitoring when we're dumping traces via
6168        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
6169        // control of all writes to the file in question.
6170        final DumpStackFileObserver observer;
6171        if (useTombstonedForJavaTraces) {
6172            observer = null;
6173        } else {
6174            // Use a FileObserver to detect when traces finish writing.
6175            // The order of traces is considered important to maintain for legibility.
6176            observer = new DumpStackFileObserver(tracesFile);
6177        }
6178
6179        // We must complete all stack dumps within 20 seconds.
6180        long remainingTime = 20 * 1000;
6181        try {
6182            if (observer != null) {
6183                observer.startWatching();
6184            }
6185
6186            // First collect all of the stacks of the most important pids.
6187            if (firstPids != null) {
6188                int num = firstPids.size();
6189                for (int i = 0; i < num; i++) {
6190                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
6191                            + firstPids.get(i));
6192                    final long timeTaken;
6193                    if (useTombstonedForJavaTraces) {
6194                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
6195                    } else {
6196                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
6197                    }
6198
6199                    remainingTime -= timeTaken;
6200                    if (remainingTime <= 0) {
6201                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
6202                            "); deadline exceeded.");
6203                        return;
6204                    }
6205
6206                    if (DEBUG_ANR) {
6207                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
6208                    }
6209                }
6210            }
6211
6212            // Next collect the stacks of the native pids
6213            if (nativePids != null) {
6214                for (int pid : nativePids) {
6215                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
6216                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
6217
6218                    final long start = SystemClock.elapsedRealtime();
6219                    Debug.dumpNativeBacktraceToFileTimeout(
6220                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
6221                    final long timeTaken = SystemClock.elapsedRealtime() - start;
6222
6223                    remainingTime -= timeTaken;
6224                    if (remainingTime <= 0) {
6225                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
6226                            "); deadline exceeded.");
6227                        return;
6228                    }
6229
6230                    if (DEBUG_ANR) {
6231                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
6232                    }
6233                }
6234            }
6235
6236            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
6237            if (extraPids != null) {
6238                for (int pid : extraPids) {
6239                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
6240
6241                    final long timeTaken;
6242                    if (useTombstonedForJavaTraces) {
6243                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
6244                    } else {
6245                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
6246                    }
6247
6248                    remainingTime -= timeTaken;
6249                    if (remainingTime <= 0) {
6250                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
6251                                "); deadline exceeded.");
6252                        return;
6253                    }
6254
6255                    if (DEBUG_ANR) {
6256                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
6257                    }
6258                }
6259            }
6260        } finally {
6261            if (observer != null) {
6262                observer.stopWatching();
6263            }
6264        }
6265    }
6266
6267    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
6268        if (true || Build.IS_USER) {
6269            return;
6270        }
6271        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
6272        if (tracesPath == null || tracesPath.length() == 0) {
6273            return;
6274        }
6275
6276        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
6277        StrictMode.allowThreadDiskWrites();
6278        try {
6279            final File tracesFile = new File(tracesPath);
6280            final File tracesDir = tracesFile.getParentFile();
6281            final File tracesTmp = new File(tracesDir, "__tmp__");
6282            try {
6283                if (tracesFile.exists()) {
6284                    tracesTmp.delete();
6285                    tracesFile.renameTo(tracesTmp);
6286                }
6287                StringBuilder sb = new StringBuilder();
6288                Time tobj = new Time();
6289                tobj.set(System.currentTimeMillis());
6290                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
6291                sb.append(": ");
6292                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
6293                sb.append(" since ");
6294                sb.append(msg);
6295                FileOutputStream fos = new FileOutputStream(tracesFile);
6296                fos.write(sb.toString().getBytes());
6297                if (app == null) {
6298                    fos.write("\n*** No application process!".getBytes());
6299                }
6300                fos.close();
6301                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
6302            } catch (IOException e) {
6303                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
6304                return;
6305            }
6306
6307            if (app != null && app.pid > 0) {
6308                ArrayList<Integer> firstPids = new ArrayList<Integer>();
6309                firstPids.add(app.pid);
6310                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
6311            }
6312
6313            File lastTracesFile = null;
6314            File curTracesFile = null;
6315            for (int i=9; i>=0; i--) {
6316                String name = String.format(Locale.US, "slow%02d.txt", i);
6317                curTracesFile = new File(tracesDir, name);
6318                if (curTracesFile.exists()) {
6319                    if (lastTracesFile != null) {
6320                        curTracesFile.renameTo(lastTracesFile);
6321                    } else {
6322                        curTracesFile.delete();
6323                    }
6324                }
6325                lastTracesFile = curTracesFile;
6326            }
6327            tracesFile.renameTo(curTracesFile);
6328            if (tracesTmp.exists()) {
6329                tracesTmp.renameTo(tracesFile);
6330            }
6331        } finally {
6332            StrictMode.setThreadPolicy(oldPolicy);
6333        }
6334    }
6335
6336    @GuardedBy("this")
6337    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
6338        if (!mLaunchWarningShown) {
6339            mLaunchWarningShown = true;
6340            mUiHandler.post(new Runnable() {
6341                @Override
6342                public void run() {
6343                    synchronized (ActivityManagerService.this) {
6344                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
6345                        d.show();
6346                        mUiHandler.postDelayed(new Runnable() {
6347                            @Override
6348                            public void run() {
6349                                synchronized (ActivityManagerService.this) {
6350                                    d.dismiss();
6351                                    mLaunchWarningShown = false;
6352                                }
6353                            }
6354                        }, 4000);
6355                    }
6356                }
6357            });
6358        }
6359    }
6360
6361    @Override
6362    public boolean clearApplicationUserData(final String packageName, boolean keepState,
6363            final IPackageDataObserver observer, int userId) {
6364        enforceNotIsolatedCaller("clearApplicationUserData");
6365        int uid = Binder.getCallingUid();
6366        int pid = Binder.getCallingPid();
6367        final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
6368                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
6369
6370        final ApplicationInfo appInfo;
6371        final boolean isInstantApp;
6372
6373        long callingId = Binder.clearCallingIdentity();
6374        try {
6375            IPackageManager pm = AppGlobals.getPackageManager();
6376            synchronized(this) {
6377                // Instant packages are not protected
6378                if (getPackageManagerInternalLocked().isPackageDataProtected(
6379                        resolvedUserId, packageName)) {
6380                    throw new SecurityException(
6381                            "Cannot clear data for a protected package: " + packageName);
6382                }
6383
6384                ApplicationInfo applicationInfo = null;
6385                try {
6386                    applicationInfo = pm.getApplicationInfo(packageName,
6387                            MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
6388                } catch (RemoteException e) {
6389                    /* ignore */
6390                }
6391                appInfo = applicationInfo;
6392
6393                final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
6394
6395                if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
6396                        pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
6397                    throw new SecurityException("PID " + pid + " does not have permission "
6398                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
6399                            + " of package " + packageName);
6400                }
6401
6402                final boolean hasInstantMetadata = getPackageManagerInternalLocked()
6403                        .hasInstantApplicationMetadata(packageName, resolvedUserId);
6404                final boolean isUninstalledAppWithoutInstantMetadata =
6405                        (appInfo == null && !hasInstantMetadata);
6406                isInstantApp = (appInfo != null && appInfo.isInstantApp())
6407                        || hasInstantMetadata;
6408                final boolean canAccessInstantApps = checkComponentPermission(
6409                        permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
6410                        == PackageManager.PERMISSION_GRANTED;
6411
6412                if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
6413                        && !canAccessInstantApps)) {
6414                    Slog.w(TAG, "Invalid packageName: " + packageName);
6415                    if (observer != null) {
6416                        try {
6417                            observer.onRemoveCompleted(packageName, false);
6418                        } catch (RemoteException e) {
6419                            Slog.i(TAG, "Observer no longer exists.");
6420                        }
6421                    }
6422                    return false;
6423                }
6424
6425                if (appInfo != null) {
6426                    forceStopPackageLocked(packageName, appInfo.uid, "clear data");
6427                    mRecentTasks.removeTasksByPackageName(packageName, resolvedUserId);
6428                }
6429            }
6430
6431            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
6432                @Override
6433                public void onRemoveCompleted(String packageName, boolean succeeded)
6434                        throws RemoteException {
6435                    if (appInfo != null) {
6436                        synchronized (ActivityManagerService.this) {
6437                            finishForceStopPackageLocked(packageName, appInfo.uid);
6438                        }
6439                    }
6440                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
6441                            Uri.fromParts("package", packageName, null));
6442                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6443                    intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6444                    intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6445                    if (isInstantApp) {
6446                        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6447                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6448                                null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6449                                resolvedUserId);
6450                    } else {
6451                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6452                                null, null, null, null, false, false, resolvedUserId);
6453                    }
6454
6455                    if (observer != null) {
6456                        observer.onRemoveCompleted(packageName, succeeded);
6457                    }
6458                }
6459            };
6460
6461            try {
6462                // Clear application user data
6463                pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6464
6465                if (appInfo != null) {
6466                    // Restore already established notification state and permission grants,
6467                    // so it told us to keep those intact -- it's about to emplace app data
6468                    // that is appropriate for those bits of system state.
6469                    if (!keepState) {
6470                        synchronized (this) {
6471                            // Remove all permissions granted from/to this package
6472                            removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true,
6473                                    false);
6474                        }
6475
6476                        // Reset notification state
6477                        INotificationManager inm = NotificationManager.getService();
6478                        inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6479                    }
6480
6481                    // Clear its scheduled jobs
6482                    JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
6483                    js.cancelJobsForUid(appInfo.uid, "clear data");
6484
6485                    // Clear its pending alarms
6486                    AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
6487                    ami.removeAlarmsForUid(appInfo.uid);
6488                }
6489            } catch (RemoteException e) {
6490            }
6491        } finally {
6492            Binder.restoreCallingIdentity(callingId);
6493        }
6494        return true;
6495    }
6496
6497    @Override
6498    public void killBackgroundProcesses(final String packageName, int userId) {
6499        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6500                != PackageManager.PERMISSION_GRANTED &&
6501                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6502                        != PackageManager.PERMISSION_GRANTED) {
6503            String msg = "Permission Denial: killBackgroundProcesses() from pid="
6504                    + Binder.getCallingPid()
6505                    + ", uid=" + Binder.getCallingUid()
6506                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6507            Slog.w(TAG, msg);
6508            throw new SecurityException(msg);
6509        }
6510
6511        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6512                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6513        long callingId = Binder.clearCallingIdentity();
6514        try {
6515            IPackageManager pm = AppGlobals.getPackageManager();
6516            synchronized(this) {
6517                int appId = -1;
6518                try {
6519                    appId = UserHandle.getAppId(
6520                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6521                } catch (RemoteException e) {
6522                }
6523                if (appId == -1) {
6524                    Slog.w(TAG, "Invalid packageName: " + packageName);
6525                    return;
6526                }
6527                killPackageProcessesLocked(packageName, appId, userId,
6528                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6529            }
6530        } finally {
6531            Binder.restoreCallingIdentity(callingId);
6532        }
6533    }
6534
6535    @Override
6536    public void killAllBackgroundProcesses() {
6537        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6538                != PackageManager.PERMISSION_GRANTED) {
6539            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6540                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6541                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6542            Slog.w(TAG, msg);
6543            throw new SecurityException(msg);
6544        }
6545
6546        final long callingId = Binder.clearCallingIdentity();
6547        try {
6548            synchronized (this) {
6549                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6550                final int NP = mProcessNames.getMap().size();
6551                for (int ip = 0; ip < NP; ip++) {
6552                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6553                    final int NA = apps.size();
6554                    for (int ia = 0; ia < NA; ia++) {
6555                        final ProcessRecord app = apps.valueAt(ia);
6556                        if (app.persistent) {
6557                            // We don't kill persistent processes.
6558                            continue;
6559                        }
6560                        if (app.removed) {
6561                            procs.add(app);
6562                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6563                            app.removed = true;
6564                            procs.add(app);
6565                        }
6566                    }
6567                }
6568
6569                final int N = procs.size();
6570                for (int i = 0; i < N; i++) {
6571                    removeProcessLocked(procs.get(i), false, true, "kill all background");
6572                }
6573
6574                mAllowLowerMemLevel = true;
6575
6576                updateOomAdjLocked();
6577                doLowMemReportIfNeededLocked(null);
6578            }
6579        } finally {
6580            Binder.restoreCallingIdentity(callingId);
6581        }
6582    }
6583
6584    /**
6585     * Kills all background processes, except those matching any of the
6586     * specified properties.
6587     *
6588     * @param minTargetSdk the target SDK version at or above which to preserve
6589     *                     processes, or {@code -1} to ignore the target SDK
6590     * @param maxProcState the process state at or below which to preserve
6591     *                     processes, or {@code -1} to ignore the process state
6592     */
6593    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6594        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6595                != PackageManager.PERMISSION_GRANTED) {
6596            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6597                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6598                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6599            Slog.w(TAG, msg);
6600            throw new SecurityException(msg);
6601        }
6602
6603        final long callingId = Binder.clearCallingIdentity();
6604        try {
6605            synchronized (this) {
6606                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6607                final int NP = mProcessNames.getMap().size();
6608                for (int ip = 0; ip < NP; ip++) {
6609                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6610                    final int NA = apps.size();
6611                    for (int ia = 0; ia < NA; ia++) {
6612                        final ProcessRecord app = apps.valueAt(ia);
6613                        if (app.removed) {
6614                            procs.add(app);
6615                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6616                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6617                            app.removed = true;
6618                            procs.add(app);
6619                        }
6620                    }
6621                }
6622
6623                final int N = procs.size();
6624                for (int i = 0; i < N; i++) {
6625                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6626                }
6627            }
6628        } finally {
6629            Binder.restoreCallingIdentity(callingId);
6630        }
6631    }
6632
6633    @Override
6634    public void forceStopPackage(final String packageName, int userId) {
6635        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6636                != PackageManager.PERMISSION_GRANTED) {
6637            String msg = "Permission Denial: forceStopPackage() from pid="
6638                    + Binder.getCallingPid()
6639                    + ", uid=" + Binder.getCallingUid()
6640                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6641            Slog.w(TAG, msg);
6642            throw new SecurityException(msg);
6643        }
6644        final int callingPid = Binder.getCallingPid();
6645        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6646                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6647        long callingId = Binder.clearCallingIdentity();
6648        try {
6649            IPackageManager pm = AppGlobals.getPackageManager();
6650            synchronized(this) {
6651                int[] users = userId == UserHandle.USER_ALL
6652                        ? mUserController.getUsers() : new int[] { userId };
6653                for (int user : users) {
6654                    int pkgUid = -1;
6655                    try {
6656                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6657                                user);
6658                    } catch (RemoteException e) {
6659                    }
6660                    if (pkgUid == -1) {
6661                        Slog.w(TAG, "Invalid packageName: " + packageName);
6662                        continue;
6663                    }
6664                    try {
6665                        pm.setPackageStoppedState(packageName, true, user);
6666                    } catch (RemoteException e) {
6667                    } catch (IllegalArgumentException e) {
6668                        Slog.w(TAG, "Failed trying to unstop package "
6669                                + packageName + ": " + e);
6670                    }
6671                    if (mUserController.isUserRunning(user, 0)) {
6672                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6673                        finishForceStopPackageLocked(packageName, pkgUid);
6674                    }
6675                }
6676            }
6677        } finally {
6678            Binder.restoreCallingIdentity(callingId);
6679        }
6680    }
6681
6682    @Override
6683    public void addPackageDependency(String packageName) {
6684        synchronized (this) {
6685            int callingPid = Binder.getCallingPid();
6686            if (callingPid == myPid()) {
6687                //  Yeah, um, no.
6688                return;
6689            }
6690            ProcessRecord proc;
6691            synchronized (mPidsSelfLocked) {
6692                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6693            }
6694            if (proc != null) {
6695                if (proc.pkgDeps == null) {
6696                    proc.pkgDeps = new ArraySet<String>(1);
6697                }
6698                proc.pkgDeps.add(packageName);
6699            }
6700        }
6701    }
6702
6703    /*
6704     * The pkg name and app id have to be specified.
6705     */
6706    @Override
6707    public void killApplication(String pkg, int appId, int userId, String reason) {
6708        if (pkg == null) {
6709            return;
6710        }
6711        // Make sure the uid is valid.
6712        if (appId < 0) {
6713            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6714            return;
6715        }
6716        int callerUid = Binder.getCallingUid();
6717        // Only the system server can kill an application
6718        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6719            // Post an aysnc message to kill the application
6720            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6721            msg.arg1 = appId;
6722            msg.arg2 = userId;
6723            Bundle bundle = new Bundle();
6724            bundle.putString("pkg", pkg);
6725            bundle.putString("reason", reason);
6726            msg.obj = bundle;
6727            mHandler.sendMessage(msg);
6728        } else {
6729            throw new SecurityException(callerUid + " cannot kill pkg: " +
6730                    pkg);
6731        }
6732    }
6733
6734    @Override
6735    public void closeSystemDialogs(String reason) {
6736        enforceNotIsolatedCaller("closeSystemDialogs");
6737
6738        final int pid = Binder.getCallingPid();
6739        final int uid = Binder.getCallingUid();
6740        final long origId = Binder.clearCallingIdentity();
6741        try {
6742            synchronized (this) {
6743                // Only allow this from foreground processes, so that background
6744                // applications can't abuse it to prevent system UI from being shown.
6745                if (uid >= FIRST_APPLICATION_UID) {
6746                    ProcessRecord proc;
6747                    synchronized (mPidsSelfLocked) {
6748                        proc = mPidsSelfLocked.get(pid);
6749                    }
6750                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6751                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6752                                + " from background process " + proc);
6753                        return;
6754                    }
6755                }
6756                closeSystemDialogsLocked(reason);
6757            }
6758        } finally {
6759            Binder.restoreCallingIdentity(origId);
6760        }
6761    }
6762
6763    @GuardedBy("this")
6764    void closeSystemDialogsLocked(String reason) {
6765        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6766        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6767                | Intent.FLAG_RECEIVER_FOREGROUND);
6768        if (reason != null) {
6769            intent.putExtra("reason", reason);
6770        }
6771        mWindowManager.closeSystemDialogs(reason);
6772
6773        mStackSupervisor.closeSystemDialogsLocked();
6774
6775        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6776                OP_NONE, null, false, false,
6777                -1, SYSTEM_UID, UserHandle.USER_ALL);
6778    }
6779
6780    @Override
6781    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6782        enforceNotIsolatedCaller("getProcessMemoryInfo");
6783        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6784        for (int i=pids.length-1; i>=0; i--) {
6785            ProcessRecord proc;
6786            int oomAdj;
6787            synchronized (this) {
6788                synchronized (mPidsSelfLocked) {
6789                    proc = mPidsSelfLocked.get(pids[i]);
6790                    oomAdj = proc != null ? proc.setAdj : 0;
6791                }
6792            }
6793            infos[i] = new Debug.MemoryInfo();
6794            long startTime = SystemClock.currentThreadTimeMillis();
6795            Debug.getMemoryInfo(pids[i], infos[i]);
6796            long endTime = SystemClock.currentThreadTimeMillis();
6797            if (proc != null) {
6798                synchronized (this) {
6799                    if (proc.thread != null && proc.setAdj == oomAdj) {
6800                        // Record this for posterity if the process has been stable.
6801                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6802                                infos[i].getTotalUss(), infos[i].getTotalRss(), false,
6803                                ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime,
6804                                proc.pkgList);
6805                    }
6806                }
6807            }
6808        }
6809        return infos;
6810    }
6811
6812    @Override
6813    public long[] getProcessPss(int[] pids) {
6814        enforceNotIsolatedCaller("getProcessPss");
6815        long[] pss = new long[pids.length];
6816        for (int i=pids.length-1; i>=0; i--) {
6817            ProcessRecord proc;
6818            int oomAdj;
6819            synchronized (this) {
6820                synchronized (mPidsSelfLocked) {
6821                    proc = mPidsSelfLocked.get(pids[i]);
6822                    oomAdj = proc != null ? proc.setAdj : 0;
6823                }
6824            }
6825            long[] tmpUss = new long[3];
6826            long startTime = SystemClock.currentThreadTimeMillis();
6827            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6828            long endTime = SystemClock.currentThreadTimeMillis();
6829            if (proc != null) {
6830                synchronized (this) {
6831                    if (proc.thread != null && proc.setAdj == oomAdj) {
6832                        // Record this for posterity if the process has been stable.
6833                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
6834                                ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList);
6835                    }
6836                }
6837            }
6838        }
6839        return pss;
6840    }
6841
6842    @Override
6843    public void killApplicationProcess(String processName, int uid) {
6844        if (processName == null) {
6845            return;
6846        }
6847
6848        int callerUid = Binder.getCallingUid();
6849        // Only the system server can kill an application
6850        if (callerUid == SYSTEM_UID) {
6851            synchronized (this) {
6852                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6853                if (app != null && app.thread != null) {
6854                    try {
6855                        app.thread.scheduleSuicide();
6856                    } catch (RemoteException e) {
6857                        // If the other end already died, then our work here is done.
6858                    }
6859                } else {
6860                    Slog.w(TAG, "Process/uid not found attempting kill of "
6861                            + processName + " / " + uid);
6862                }
6863            }
6864        } else {
6865            throw new SecurityException(callerUid + " cannot kill app process: " +
6866                    processName);
6867        }
6868    }
6869
6870    @GuardedBy("this")
6871    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6872        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6873                false, true, false, false, UserHandle.getUserId(uid), reason);
6874    }
6875
6876    @GuardedBy("this")
6877    private void finishForceStopPackageLocked(final String packageName, int uid) {
6878        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6879                Uri.fromParts("package", packageName, null));
6880        if (!mProcessesReady) {
6881            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6882                    | Intent.FLAG_RECEIVER_FOREGROUND);
6883        }
6884        intent.putExtra(Intent.EXTRA_UID, uid);
6885        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6886        broadcastIntentLocked(null, null, intent,
6887                null, null, 0, null, null, null, OP_NONE,
6888                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6889    }
6890
6891
6892    @GuardedBy("this")
6893    private final boolean killPackageProcessesLocked(String packageName, int appId,
6894            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6895            boolean doit, boolean evenPersistent, String reason) {
6896        ArrayList<ProcessRecord> procs = new ArrayList<>();
6897
6898        // Remove all processes this package may have touched: all with the
6899        // same UID (except for the system or root user), and all whose name
6900        // matches the package name.
6901        final int NP = mProcessNames.getMap().size();
6902        for (int ip=0; ip<NP; ip++) {
6903            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6904            final int NA = apps.size();
6905            for (int ia=0; ia<NA; ia++) {
6906                ProcessRecord app = apps.valueAt(ia);
6907                if (app.persistent && !evenPersistent) {
6908                    // we don't kill persistent processes
6909                    continue;
6910                }
6911                if (app.removed) {
6912                    if (doit) {
6913                        procs.add(app);
6914                    }
6915                    continue;
6916                }
6917
6918                // Skip process if it doesn't meet our oom adj requirement.
6919                if (app.setAdj < minOomAdj) {
6920                    continue;
6921                }
6922
6923                // If no package is specified, we call all processes under the
6924                // give user id.
6925                if (packageName == null) {
6926                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6927                        continue;
6928                    }
6929                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6930                        continue;
6931                    }
6932                // Package has been specified, we want to hit all processes
6933                // that match it.  We need to qualify this by the processes
6934                // that are running under the specified app and user ID.
6935                } else {
6936                    final boolean isDep = app.pkgDeps != null
6937                            && app.pkgDeps.contains(packageName);
6938                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6939                        continue;
6940                    }
6941                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6942                        continue;
6943                    }
6944                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6945                        continue;
6946                    }
6947                }
6948
6949                // Process has passed all conditions, kill it!
6950                if (!doit) {
6951                    return true;
6952                }
6953                app.removed = true;
6954                procs.add(app);
6955            }
6956        }
6957
6958        int N = procs.size();
6959        for (int i=0; i<N; i++) {
6960            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6961        }
6962        updateOomAdjLocked();
6963        return N > 0;
6964    }
6965
6966    private void cleanupDisabledPackageComponentsLocked(
6967            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6968
6969        Set<String> disabledClasses = null;
6970        boolean packageDisabled = false;
6971        IPackageManager pm = AppGlobals.getPackageManager();
6972
6973        if (changedClasses == null) {
6974            // Nothing changed...
6975            return;
6976        }
6977
6978        // Determine enable/disable state of the package and its components.
6979        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6980        for (int i = changedClasses.length - 1; i >= 0; i--) {
6981            final String changedClass = changedClasses[i];
6982
6983            if (changedClass.equals(packageName)) {
6984                try {
6985                    // Entire package setting changed
6986                    enabled = pm.getApplicationEnabledSetting(packageName,
6987                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6988                } catch (Exception e) {
6989                    // No such package/component; probably racing with uninstall.  In any
6990                    // event it means we have nothing further to do here.
6991                    return;
6992                }
6993                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6994                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6995                if (packageDisabled) {
6996                    // Entire package is disabled.
6997                    // No need to continue to check component states.
6998                    disabledClasses = null;
6999                    break;
7000                }
7001            } else {
7002                try {
7003                    enabled = pm.getComponentEnabledSetting(
7004                            new ComponentName(packageName, changedClass),
7005                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
7006                } catch (Exception e) {
7007                    // As above, probably racing with uninstall.
7008                    return;
7009                }
7010                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
7011                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
7012                    if (disabledClasses == null) {
7013                        disabledClasses = new ArraySet<>(changedClasses.length);
7014                    }
7015                    disabledClasses.add(changedClass);
7016                }
7017            }
7018        }
7019
7020        if (!packageDisabled && disabledClasses == null) {
7021            // Nothing to do here...
7022            return;
7023        }
7024
7025        // Clean-up disabled activities.
7026        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7027                packageName, disabledClasses, true, false, userId) && mBooted) {
7028            mStackSupervisor.resumeFocusedStackTopActivityLocked();
7029            mStackSupervisor.scheduleIdleLocked();
7030        }
7031
7032        // Clean-up disabled tasks
7033        mRecentTasks.cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
7034
7035        // Clean-up disabled services.
7036        mServices.bringDownDisabledPackageServicesLocked(
7037                packageName, disabledClasses, userId, false, killProcess, true);
7038
7039        // Clean-up disabled providers.
7040        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7041        mProviderMap.collectPackageProvidersLocked(
7042                packageName, disabledClasses, true, false, userId, providers);
7043        for (int i = providers.size() - 1; i >= 0; i--) {
7044            removeDyingProviderLocked(null, providers.get(i), true);
7045        }
7046
7047        // Clean-up disabled broadcast receivers.
7048        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7049            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7050                    packageName, disabledClasses, userId, true);
7051        }
7052
7053    }
7054
7055    final boolean clearBroadcastQueueForUserLocked(int userId) {
7056        boolean didSomething = false;
7057        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
7058            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7059                    null, null, userId, true);
7060        }
7061        return didSomething;
7062    }
7063
7064    @GuardedBy("this")
7065    final boolean forceStopPackageLocked(String packageName, int appId,
7066            boolean callerWillRestart, boolean purgeCache, boolean doit,
7067            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
7068        int i;
7069
7070        if (userId == UserHandle.USER_ALL && packageName == null) {
7071            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
7072        }
7073
7074        if (appId < 0 && packageName != null) {
7075            try {
7076                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
7077                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
7078            } catch (RemoteException e) {
7079            }
7080        }
7081
7082        if (doit) {
7083            if (packageName != null) {
7084                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
7085                        + " user=" + userId + ": " + reason);
7086            } else {
7087                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
7088            }
7089
7090            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
7091        }
7092
7093        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
7094                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
7095                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
7096
7097        didSomething |= mActivityStartController.clearPendingActivityLaunches(packageName);
7098
7099        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
7100                packageName, null, doit, evenPersistent, userId)) {
7101            if (!doit) {
7102                return true;
7103            }
7104            didSomething = true;
7105        }
7106
7107        if (mServices.bringDownDisabledPackageServicesLocked(
7108                packageName, null, userId, evenPersistent, true, doit)) {
7109            if (!doit) {
7110                return true;
7111            }
7112            didSomething = true;
7113        }
7114
7115        if (packageName == null) {
7116            // Remove all sticky broadcasts from this user.
7117            mStickyBroadcasts.remove(userId);
7118        }
7119
7120        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
7121        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
7122                userId, providers)) {
7123            if (!doit) {
7124                return true;
7125            }
7126            didSomething = true;
7127        }
7128        for (i = providers.size() - 1; i >= 0; i--) {
7129            removeDyingProviderLocked(null, providers.get(i), true);
7130        }
7131
7132        // Remove transient permissions granted from/to this package/user
7133        removeUriPermissionsForPackageLocked(packageName, userId, false, false);
7134
7135        if (doit) {
7136            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
7137                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
7138                        packageName, null, userId, doit);
7139            }
7140        }
7141
7142        if (packageName == null || uninstalling) {
7143            // Remove pending intents.  For now we only do this when force
7144            // stopping users, because we have some problems when doing this
7145            // for packages -- app widgets are not currently cleaned up for
7146            // such packages, so they can be left with bad pending intents.
7147            if (mIntentSenderRecords.size() > 0) {
7148                Iterator<WeakReference<PendingIntentRecord>> it
7149                        = mIntentSenderRecords.values().iterator();
7150                while (it.hasNext()) {
7151                    WeakReference<PendingIntentRecord> wpir = it.next();
7152                    if (wpir == null) {
7153                        it.remove();
7154                        continue;
7155                    }
7156                    PendingIntentRecord pir = wpir.get();
7157                    if (pir == null) {
7158                        it.remove();
7159                        continue;
7160                    }
7161                    if (packageName == null) {
7162                        // Stopping user, remove all objects for the user.
7163                        if (pir.key.userId != userId) {
7164                            // Not the same user, skip it.
7165                            continue;
7166                        }
7167                    } else {
7168                        if (UserHandle.getAppId(pir.uid) != appId) {
7169                            // Different app id, skip it.
7170                            continue;
7171                        }
7172                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
7173                            // Different user, skip it.
7174                            continue;
7175                        }
7176                        if (!pir.key.packageName.equals(packageName)) {
7177                            // Different package, skip it.
7178                            continue;
7179                        }
7180                    }
7181                    if (!doit) {
7182                        return true;
7183                    }
7184                    didSomething = true;
7185                    it.remove();
7186                    makeIntentSenderCanceledLocked(pir);
7187                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
7188                        pir.key.activity.pendingResults.remove(pir.ref);
7189                    }
7190                }
7191            }
7192        }
7193
7194        if (doit) {
7195            if (purgeCache && packageName != null) {
7196                AttributeCache ac = AttributeCache.instance();
7197                if (ac != null) {
7198                    ac.removePackage(packageName);
7199                }
7200            }
7201            if (mBooted) {
7202                mStackSupervisor.resumeFocusedStackTopActivityLocked();
7203                mStackSupervisor.scheduleIdleLocked();
7204            }
7205        }
7206
7207        return didSomething;
7208    }
7209
7210    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
7211        return removeProcessNameLocked(name, uid, null);
7212    }
7213
7214    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
7215            final ProcessRecord expecting) {
7216        ProcessRecord old = mProcessNames.get(name, uid);
7217        // Only actually remove when the currently recorded value matches the
7218        // record that we expected; if it doesn't match then we raced with a
7219        // newly created process and we don't want to destroy the new one.
7220        if ((expecting == null) || (old == expecting)) {
7221            mProcessNames.remove(name, uid);
7222        }
7223        if (old != null && old.uidRecord != null) {
7224            old.uidRecord.numProcs--;
7225            if (old.uidRecord.numProcs == 0) {
7226                // No more processes using this uid, tell clients it is gone.
7227                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7228                        "No more processes in " + old.uidRecord);
7229                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
7230                EventLogTags.writeAmUidStopped(uid);
7231                mActiveUids.remove(uid);
7232                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
7233            }
7234            old.uidRecord = null;
7235        }
7236        mIsolatedProcesses.remove(uid);
7237        return old;
7238    }
7239
7240    private final void addProcessNameLocked(ProcessRecord proc) {
7241        // We shouldn't already have a process under this name, but just in case we
7242        // need to clean up whatever may be there now.
7243        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
7244        if (old == proc && proc.persistent) {
7245            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
7246            Slog.w(TAG, "Re-adding persistent process " + proc);
7247        } else if (old != null) {
7248            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
7249        }
7250        UidRecord uidRec = mActiveUids.get(proc.uid);
7251        if (uidRec == null) {
7252            uidRec = new UidRecord(proc.uid);
7253            // This is the first appearance of the uid, report it now!
7254            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
7255                    "Creating new process uid: " + uidRec);
7256            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
7257                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
7258                uidRec.setWhitelist = uidRec.curWhitelist = true;
7259            }
7260            uidRec.updateHasInternetPermission();
7261            mActiveUids.put(proc.uid, uidRec);
7262            EventLogTags.writeAmUidRunning(uidRec.uid);
7263            noteUidProcessState(uidRec.uid, uidRec.curProcState);
7264        }
7265        proc.uidRecord = uidRec;
7266
7267        // Reset render thread tid if it was already set, so new process can set it again.
7268        proc.renderThreadTid = 0;
7269        uidRec.numProcs++;
7270        mProcessNames.put(proc.processName, proc.uid, proc);
7271        if (proc.isolated) {
7272            mIsolatedProcesses.put(proc.uid, proc);
7273        }
7274    }
7275
7276    @GuardedBy("this")
7277    boolean removeProcessLocked(ProcessRecord app,
7278            boolean callerWillRestart, boolean allowRestart, String reason) {
7279        final String name = app.processName;
7280        final int uid = app.uid;
7281        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
7282            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
7283
7284        ProcessRecord old = mProcessNames.get(name, uid);
7285        if (old != app) {
7286            // This process is no longer active, so nothing to do.
7287            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
7288            return false;
7289        }
7290        removeProcessNameLocked(name, uid);
7291        if (mHeavyWeightProcess == app) {
7292            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7293                    mHeavyWeightProcess.userId, 0));
7294            mHeavyWeightProcess = null;
7295        }
7296        boolean needRestart = false;
7297        if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
7298            int pid = app.pid;
7299            if (pid > 0) {
7300                synchronized (mPidsSelfLocked) {
7301                    mPidsSelfLocked.remove(pid);
7302                    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7303                }
7304                mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7305                if (app.isolated) {
7306                    mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7307                    getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
7308                }
7309            }
7310            boolean willRestart = false;
7311            if (app.persistent && !app.isolated) {
7312                if (!callerWillRestart) {
7313                    willRestart = true;
7314                } else {
7315                    needRestart = true;
7316                }
7317            }
7318            app.kill(reason, true);
7319            handleAppDiedLocked(app, willRestart, allowRestart);
7320            if (willRestart) {
7321                removeLruProcessLocked(app);
7322                addAppLocked(app.info, null, false, null /* ABI override */);
7323            }
7324        } else {
7325            mRemovedProcesses.add(app);
7326        }
7327
7328        return needRestart;
7329    }
7330
7331    @GuardedBy("this")
7332    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
7333        cleanupAppInLaunchingProvidersLocked(app, true);
7334        removeProcessLocked(app, false, true, "timeout publishing content providers");
7335    }
7336
7337    private final void processStartTimedOutLocked(ProcessRecord app) {
7338        final int pid = app.pid;
7339        boolean gone = false;
7340        synchronized (mPidsSelfLocked) {
7341            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
7342            if (knownApp != null && knownApp.thread == null) {
7343                mPidsSelfLocked.remove(pid);
7344                gone = true;
7345            }
7346        }
7347
7348        if (gone) {
7349            Slog.w(TAG, "Process " + app + " failed to attach");
7350            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
7351                    pid, app.uid, app.processName);
7352            removeProcessNameLocked(app.processName, app.uid);
7353            if (mHeavyWeightProcess == app) {
7354                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
7355                        mHeavyWeightProcess.userId, 0));
7356                mHeavyWeightProcess = null;
7357            }
7358            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
7359            // Take care of any launching providers waiting for this process.
7360            cleanupAppInLaunchingProvidersLocked(app, true);
7361            // Take care of any services that are waiting for the process.
7362            mServices.processStartTimedOutLocked(app);
7363            app.kill("start timeout", true);
7364            if (app.isolated) {
7365                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
7366            }
7367            removeLruProcessLocked(app);
7368            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
7369                Slog.w(TAG, "Unattached app died before backup, skipping");
7370                mHandler.post(new Runnable() {
7371                @Override
7372                    public void run(){
7373                        try {
7374                            IBackupManager bm = IBackupManager.Stub.asInterface(
7375                                    ServiceManager.getService(Context.BACKUP_SERVICE));
7376                            bm.agentDisconnected(app.info.packageName);
7377                        } catch (RemoteException e) {
7378                            // Can't happen; the backup manager is local
7379                        }
7380                    }
7381                });
7382            }
7383            if (isPendingBroadcastProcessLocked(pid)) {
7384                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
7385                skipPendingBroadcastLocked(pid);
7386            }
7387        } else {
7388            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
7389        }
7390    }
7391
7392    @GuardedBy("this")
7393    private final boolean attachApplicationLocked(IApplicationThread thread,
7394            int pid, int callingUid, long startSeq) {
7395
7396        // Find the application record that is being attached...  either via
7397        // the pid if we are running in multiple processes, or just pull the
7398        // next app record if we are emulating process with anonymous threads.
7399        ProcessRecord app;
7400        long startTime = SystemClock.uptimeMillis();
7401        if (pid != MY_PID && pid >= 0) {
7402            synchronized (mPidsSelfLocked) {
7403                app = mPidsSelfLocked.get(pid);
7404            }
7405        } else {
7406            app = null;
7407        }
7408
7409        // It's possible that process called attachApplication before we got a chance to
7410        // update the internal state.
7411        if (app == null && startSeq > 0) {
7412            final ProcessRecord pending = mPendingStarts.get(startSeq);
7413            if (pending != null && pending.startUid == callingUid
7414                    && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
7415                            startSeq, true)) {
7416                app = pending;
7417            }
7418        }
7419
7420        if (app == null) {
7421            Slog.w(TAG, "No pending application record for pid " + pid
7422                    + " (IApplicationThread " + thread + "); dropping process");
7423            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
7424            if (pid > 0 && pid != MY_PID) {
7425                killProcessQuiet(pid);
7426                //TODO: killProcessGroup(app.info.uid, pid);
7427            } else {
7428                try {
7429                    thread.scheduleExit();
7430                } catch (Exception e) {
7431                    // Ignore exceptions.
7432                }
7433            }
7434            return false;
7435        }
7436
7437        // If this application record is still attached to a previous
7438        // process, clean it up now.
7439        if (app.thread != null) {
7440            handleAppDiedLocked(app, true, true);
7441        }
7442
7443        // Tell the process all about itself.
7444
7445        if (DEBUG_ALL) Slog.v(
7446                TAG, "Binding process pid " + pid + " to record " + app);
7447
7448        final String processName = app.processName;
7449        try {
7450            AppDeathRecipient adr = new AppDeathRecipient(
7451                    app, pid, thread);
7452            thread.asBinder().linkToDeath(adr, 0);
7453            app.deathRecipient = adr;
7454        } catch (RemoteException e) {
7455            app.resetPackageList(mProcessStats);
7456            startProcessLocked(app, "link fail", processName);
7457            return false;
7458        }
7459
7460        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
7461
7462        app.makeActive(thread, mProcessStats);
7463        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
7464        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
7465        app.forcingToImportant = null;
7466        updateProcessForegroundLocked(app, false, false);
7467        app.hasShownUi = false;
7468        app.debugging = false;
7469        app.cached = false;
7470        app.killedByAm = false;
7471        app.killed = false;
7472
7473
7474        // We carefully use the same state that PackageManager uses for
7475        // filtering, since we use this flag to decide if we need to install
7476        // providers when user is unlocked later
7477        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
7478
7479        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7480
7481        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
7482        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
7483
7484        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7485            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7486            msg.obj = app;
7487            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7488        }
7489
7490        checkTime(startTime, "attachApplicationLocked: before bindApplication");
7491
7492        if (!normalMode) {
7493            Slog.i(TAG, "Launching preboot mode app: " + app);
7494        }
7495
7496        if (DEBUG_ALL) Slog.v(
7497            TAG, "New app record " + app
7498            + " thread=" + thread.asBinder() + " pid=" + pid);
7499        try {
7500            int testMode = ApplicationThreadConstants.DEBUG_OFF;
7501            if (mDebugApp != null && mDebugApp.equals(processName)) {
7502                testMode = mWaitForDebugger
7503                    ? ApplicationThreadConstants.DEBUG_WAIT
7504                    : ApplicationThreadConstants.DEBUG_ON;
7505                app.debugging = true;
7506                if (mDebugTransient) {
7507                    mDebugApp = mOrigDebugApp;
7508                    mWaitForDebugger = mOrigWaitForDebugger;
7509                }
7510            }
7511
7512            boolean enableTrackAllocation = false;
7513            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7514                enableTrackAllocation = true;
7515                mTrackAllocationApp = null;
7516            }
7517
7518            // If the app is being launched for restore or full backup, set it up specially
7519            boolean isRestrictedBackupMode = false;
7520            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7521                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7522                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7523                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7524                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7525            }
7526
7527            if (app.instr != null) {
7528                notifyPackageUse(app.instr.mClass.getPackageName(),
7529                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7530            }
7531            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7532                    + processName + " with config " + getGlobalConfiguration());
7533            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7534            app.compat = compatibilityInfoForPackageLocked(appInfo);
7535
7536            ProfilerInfo profilerInfo = null;
7537            String preBindAgent = null;
7538            if (mProfileApp != null && mProfileApp.equals(processName)) {
7539                mProfileProc = app;
7540                if (mProfilerInfo != null) {
7541                    // Send a profiler info object to the app if either a file is given, or
7542                    // an agent should be loaded at bind-time.
7543                    boolean needsInfo = mProfilerInfo.profileFile != null
7544                            || mProfilerInfo.attachAgentDuringBind;
7545                    profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7546                    if (mProfilerInfo.agent != null) {
7547                        preBindAgent = mProfilerInfo.agent;
7548                    }
7549                }
7550            } else if (app.instr != null && app.instr.mProfileFile != null) {
7551                profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7552                        null, false);
7553            }
7554            if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
7555                // We need to do a debuggable check here. See setAgentApp for why the check is
7556                // postponed to here.
7557                if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
7558                    String agent = mAppAgentMap.get(processName);
7559                    // Do not overwrite already requested agent.
7560                    if (profilerInfo == null) {
7561                        profilerInfo = new ProfilerInfo(null, null, 0, false, false,
7562                                mAppAgentMap.get(processName), true);
7563                    } else if (profilerInfo.agent == null) {
7564                        profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
7565                    }
7566                }
7567            }
7568
7569            if (profilerInfo != null && profilerInfo.profileFd != null) {
7570                profilerInfo.profileFd = profilerInfo.profileFd.dup();
7571            }
7572
7573            // We deprecated Build.SERIAL and it is not accessible to
7574            // apps that target the v2 security sandbox and to apps that
7575            // target APIs higher than O MR1. Since access to the serial
7576            // is now behind a permission we push down the value.
7577            final String buildSerial = (appInfo.targetSandboxVersion < 2
7578                    && appInfo.targetSdkVersion <= Build.VERSION_CODES.O_MR1)
7579                            ? sTheRealBuildSerial : Build.UNKNOWN;
7580
7581            // Check if this is a secondary process that should be incorporated into some
7582            // currently active instrumentation.  (Note we do this AFTER all of the profiling
7583            // stuff above because profiling can currently happen only in the primary
7584            // instrumentation process.)
7585            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7586                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7587                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7588                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7589                        if (aInstr.mTargetProcesses.length == 0) {
7590                            // This is the wildcard mode, where every process brought up for
7591                            // the target instrumentation should be included.
7592                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7593                                app.instr = aInstr;
7594                                aInstr.mRunningProcesses.add(app);
7595                            }
7596                        } else {
7597                            for (String proc : aInstr.mTargetProcesses) {
7598                                if (proc.equals(app.processName)) {
7599                                    app.instr = aInstr;
7600                                    aInstr.mRunningProcesses.add(app);
7601                                    break;
7602                                }
7603                            }
7604                        }
7605                    }
7606                }
7607            }
7608
7609            // If we were asked to attach an agent on startup, do so now, before we're binding
7610            // application code.
7611            if (preBindAgent != null) {
7612                thread.attachAgent(preBindAgent);
7613            }
7614
7615
7616            // Figure out whether the app needs to run in autofill compat mode.
7617            boolean isAutofillCompatEnabled = false;
7618            if (UserHandle.getAppId(app.info.uid) >= Process.FIRST_APPLICATION_UID) {
7619                final AutofillManagerInternal afm = LocalServices.getService(
7620                        AutofillManagerInternal.class);
7621                if (afm != null) {
7622                    isAutofillCompatEnabled = afm.isCompatibilityModeRequested(
7623                            app.info.packageName, app.info.versionCode, app.userId);
7624                }
7625            }
7626
7627            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7628            mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
7629            if (app.isolatedEntryPoint != null) {
7630                // This is an isolated process which should just call an entry point instead of
7631                // being bound to an application.
7632                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
7633            } else if (app.instr != null) {
7634                thread.bindApplication(processName, appInfo, providers,
7635                        app.instr.mClass,
7636                        profilerInfo, app.instr.mArguments,
7637                        app.instr.mWatcher,
7638                        app.instr.mUiAutomationConnection, testMode,
7639                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7640                        isRestrictedBackupMode || !normalMode, app.persistent,
7641                        new Configuration(getGlobalConfiguration()), app.compat,
7642                        getCommonServicesLocked(app.isolated),
7643                        mCoreSettingsObserver.getCoreSettingsLocked(),
7644                        buildSerial, isAutofillCompatEnabled);
7645            } else {
7646                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7647                        null, null, null, testMode,
7648                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7649                        isRestrictedBackupMode || !normalMode, app.persistent,
7650                        new Configuration(getGlobalConfiguration()), app.compat,
7651                        getCommonServicesLocked(app.isolated),
7652                        mCoreSettingsObserver.getCoreSettingsLocked(),
7653                        buildSerial, isAutofillCompatEnabled);
7654            }
7655
7656            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7657            updateLruProcessLocked(app, false, null);
7658            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7659            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7660        } catch (Exception e) {
7661            // todo: Yikes!  What should we do?  For now we will try to
7662            // start another process, but that could easily get us in
7663            // an infinite loop of restarting processes...
7664            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7665
7666            app.resetPackageList(mProcessStats);
7667            app.unlinkDeathRecipient();
7668            startProcessLocked(app, "bind fail", processName);
7669            return false;
7670        }
7671
7672        // Remove this record from the list of starting applications.
7673        mPersistentStartingProcesses.remove(app);
7674        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7675                "Attach application locked removing on hold: " + app);
7676        mProcessesOnHold.remove(app);
7677
7678        boolean badApp = false;
7679        boolean didSomething = false;
7680
7681        // See if the top visible activity is waiting to run in this process...
7682        if (normalMode) {
7683            try {
7684                if (mStackSupervisor.attachApplicationLocked(app)) {
7685                    didSomething = true;
7686                }
7687            } catch (Exception e) {
7688                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7689                badApp = true;
7690            }
7691        }
7692
7693        // Find any services that should be running in this process...
7694        if (!badApp) {
7695            try {
7696                didSomething |= mServices.attachApplicationLocked(app, processName);
7697                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7698            } catch (Exception e) {
7699                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7700                badApp = true;
7701            }
7702        }
7703
7704        // Check if a next-broadcast receiver is in this process...
7705        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7706            try {
7707                didSomething |= sendPendingBroadcastsLocked(app);
7708                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7709            } catch (Exception e) {
7710                // If the app died trying to launch the receiver we declare it 'bad'
7711                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7712                badApp = true;
7713            }
7714        }
7715
7716        // Check whether the next backup agent is in this process...
7717        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7718            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7719                    "New app is backup target, launching agent for " + app);
7720            notifyPackageUse(mBackupTarget.appInfo.packageName,
7721                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7722            try {
7723                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7724                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7725                        mBackupTarget.backupMode);
7726            } catch (Exception e) {
7727                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7728                badApp = true;
7729            }
7730        }
7731
7732        if (badApp) {
7733            app.kill("error during init", true);
7734            handleAppDiedLocked(app, false, true);
7735            return false;
7736        }
7737
7738        if (!didSomething) {
7739            updateOomAdjLocked();
7740            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7741        }
7742
7743        return true;
7744    }
7745
7746    @Override
7747    public final void attachApplication(IApplicationThread thread, long startSeq) {
7748        synchronized (this) {
7749            int callingPid = Binder.getCallingPid();
7750            final int callingUid = Binder.getCallingUid();
7751            final long origId = Binder.clearCallingIdentity();
7752            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
7753            Binder.restoreCallingIdentity(origId);
7754        }
7755    }
7756
7757    @Override
7758    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7759        final long origId = Binder.clearCallingIdentity();
7760        synchronized (this) {
7761            ActivityStack stack = ActivityRecord.getStackLocked(token);
7762            if (stack != null) {
7763                ActivityRecord r =
7764                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7765                                false /* processPausingActivities */, config);
7766                if (stopProfiling) {
7767                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
7768                        clearProfilerLocked();
7769                    }
7770                }
7771            }
7772        }
7773        Binder.restoreCallingIdentity(origId);
7774    }
7775
7776    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7777        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7778                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7779    }
7780
7781    void enableScreenAfterBoot() {
7782        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7783                SystemClock.uptimeMillis());
7784        mWindowManager.enableScreenAfterBoot();
7785
7786        synchronized (this) {
7787            updateEventDispatchingLocked();
7788        }
7789    }
7790
7791    @Override
7792    public void showBootMessage(final CharSequence msg, final boolean always) {
7793        if (Binder.getCallingUid() != myUid()) {
7794            throw new SecurityException();
7795        }
7796        mWindowManager.showBootMessage(msg, always);
7797    }
7798
7799    @Override
7800    public void keyguardGoingAway(int flags) {
7801        enforceNotIsolatedCaller("keyguardGoingAway");
7802        final long token = Binder.clearCallingIdentity();
7803        try {
7804            synchronized (this) {
7805                mKeyguardController.keyguardGoingAway(flags);
7806            }
7807        } finally {
7808            Binder.restoreCallingIdentity(token);
7809        }
7810    }
7811
7812    /**
7813     * @return whther the keyguard is currently locked.
7814     */
7815    boolean isKeyguardLocked() {
7816        return mKeyguardController.isKeyguardLocked();
7817    }
7818
7819    final void finishBooting() {
7820        synchronized (this) {
7821            if (!mBootAnimationComplete) {
7822                mCallFinishBooting = true;
7823                return;
7824            }
7825            mCallFinishBooting = false;
7826        }
7827
7828        ArraySet<String> completedIsas = new ArraySet<String>();
7829        for (String abi : Build.SUPPORTED_ABIS) {
7830            zygoteProcess.establishZygoteConnectionForAbi(abi);
7831            final String instructionSet = VMRuntime.getInstructionSet(abi);
7832            if (!completedIsas.contains(instructionSet)) {
7833                try {
7834                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7835                } catch (InstallerException e) {
7836                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7837                            e.getMessage() +")");
7838                }
7839                completedIsas.add(instructionSet);
7840            }
7841        }
7842
7843        IntentFilter pkgFilter = new IntentFilter();
7844        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7845        pkgFilter.addDataScheme("package");
7846        mContext.registerReceiver(new BroadcastReceiver() {
7847            @Override
7848            public void onReceive(Context context, Intent intent) {
7849                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7850                if (pkgs != null) {
7851                    for (String pkg : pkgs) {
7852                        synchronized (ActivityManagerService.this) {
7853                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7854                                    0, "query restart")) {
7855                                setResultCode(Activity.RESULT_OK);
7856                                return;
7857                            }
7858                        }
7859                    }
7860                }
7861            }
7862        }, pkgFilter);
7863
7864        IntentFilter dumpheapFilter = new IntentFilter();
7865        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7866        mContext.registerReceiver(new BroadcastReceiver() {
7867            @Override
7868            public void onReceive(Context context, Intent intent) {
7869                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7870                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7871                } else {
7872                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7873                }
7874            }
7875        }, dumpheapFilter);
7876
7877        // Let system services know.
7878        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7879
7880        synchronized (this) {
7881            // Ensure that any processes we had put on hold are now started
7882            // up.
7883            final int NP = mProcessesOnHold.size();
7884            if (NP > 0) {
7885                ArrayList<ProcessRecord> procs =
7886                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7887                for (int ip=0; ip<NP; ip++) {
7888                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7889                            + procs.get(ip));
7890                    startProcessLocked(procs.get(ip), "on-hold", null);
7891                }
7892            }
7893            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7894                return;
7895            }
7896            // Start looking for apps that are abusing wake locks.
7897            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7898            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7899            // Tell anyone interested that we are done booting!
7900            SystemProperties.set("sys.boot_completed", "1");
7901
7902            // And trigger dev.bootcomplete if we are not showing encryption progress
7903            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7904                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7905                SystemProperties.set("dev.bootcomplete", "1");
7906            }
7907            mUserController.sendBootCompleted(
7908                    new IIntentReceiver.Stub() {
7909                        @Override
7910                        public void performReceive(Intent intent, int resultCode,
7911                                String data, Bundle extras, boolean ordered,
7912                                boolean sticky, int sendingUser) {
7913                            synchronized (ActivityManagerService.this) {
7914                                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
7915                            }
7916                        }
7917                    });
7918            mUserController.scheduleStartProfiles();
7919        }
7920    }
7921
7922    @Override
7923    public void bootAnimationComplete() {
7924        final boolean callFinishBooting;
7925        synchronized (this) {
7926            callFinishBooting = mCallFinishBooting;
7927            mBootAnimationComplete = true;
7928        }
7929        if (callFinishBooting) {
7930            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7931            finishBooting();
7932            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7933        }
7934    }
7935
7936    final void ensureBootCompleted() {
7937        boolean booting;
7938        boolean enableScreen;
7939        synchronized (this) {
7940            booting = mBooting;
7941            mBooting = false;
7942            enableScreen = !mBooted;
7943            mBooted = true;
7944        }
7945
7946        if (booting) {
7947            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7948            finishBooting();
7949            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7950        }
7951
7952        if (enableScreen) {
7953            enableScreenAfterBoot();
7954        }
7955    }
7956
7957    @Override
7958    public final void activityResumed(IBinder token) {
7959        final long origId = Binder.clearCallingIdentity();
7960        synchronized(this) {
7961            ActivityRecord.activityResumedLocked(token);
7962            mWindowManager.notifyAppResumedFinished(token);
7963        }
7964        Binder.restoreCallingIdentity(origId);
7965    }
7966
7967    @Override
7968    public final void activityPaused(IBinder token) {
7969        final long origId = Binder.clearCallingIdentity();
7970        synchronized(this) {
7971            ActivityStack stack = ActivityRecord.getStackLocked(token);
7972            if (stack != null) {
7973                stack.activityPausedLocked(token, false);
7974            }
7975        }
7976        Binder.restoreCallingIdentity(origId);
7977    }
7978
7979    @Override
7980    public final void activityStopped(IBinder token, Bundle icicle,
7981            PersistableBundle persistentState, CharSequence description) {
7982        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7983
7984        // Refuse possible leaked file descriptors
7985        if (icicle != null && icicle.hasFileDescriptors()) {
7986            throw new IllegalArgumentException("File descriptors passed in Bundle");
7987        }
7988
7989        final long origId = Binder.clearCallingIdentity();
7990
7991        synchronized (this) {
7992            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7993            if (r != null) {
7994                r.activityStoppedLocked(icicle, persistentState, description);
7995            }
7996        }
7997
7998        trimApplications();
7999
8000        Binder.restoreCallingIdentity(origId);
8001    }
8002
8003    @Override
8004    public final void activityDestroyed(IBinder token) {
8005        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
8006        synchronized (this) {
8007            ActivityStack stack = ActivityRecord.getStackLocked(token);
8008            if (stack != null) {
8009                stack.activityDestroyedLocked(token, "activityDestroyed");
8010            }
8011        }
8012    }
8013
8014    @Override
8015    public final void activityRelaunched(IBinder token) {
8016        final long origId = Binder.clearCallingIdentity();
8017        synchronized (this) {
8018            mStackSupervisor.activityRelaunchedLocked(token);
8019        }
8020        Binder.restoreCallingIdentity(origId);
8021    }
8022
8023    @Override
8024    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
8025            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
8026        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
8027                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
8028        synchronized (this) {
8029            ActivityRecord record = ActivityRecord.isInStackLocked(token);
8030            if (record == null) {
8031                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
8032                        + "found for: " + token);
8033            }
8034            record.setSizeConfigurations(horizontalSizeConfiguration,
8035                    verticalSizeConfigurations, smallestSizeConfigurations);
8036        }
8037    }
8038
8039    @Override
8040    public final void notifyLaunchTaskBehindComplete(IBinder token) {
8041        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
8042    }
8043
8044    @Override
8045    public final void notifyEnterAnimationComplete(IBinder token) {
8046        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
8047    }
8048
8049    @Override
8050    public String getCallingPackage(IBinder token) {
8051        synchronized (this) {
8052            ActivityRecord r = getCallingRecordLocked(token);
8053            return r != null ? r.info.packageName : null;
8054        }
8055    }
8056
8057    @Override
8058    public ComponentName getCallingActivity(IBinder token) {
8059        synchronized (this) {
8060            ActivityRecord r = getCallingRecordLocked(token);
8061            return r != null ? r.intent.getComponent() : null;
8062        }
8063    }
8064
8065    private ActivityRecord getCallingRecordLocked(IBinder token) {
8066        ActivityRecord r = ActivityRecord.isInStackLocked(token);
8067        if (r == null) {
8068            return null;
8069        }
8070        return r.resultTo;
8071    }
8072
8073    @Override
8074    public ComponentName getActivityClassForToken(IBinder token) {
8075        synchronized(this) {
8076            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8077            if (r == null) {
8078                return null;
8079            }
8080            return r.intent.getComponent();
8081        }
8082    }
8083
8084    @Override
8085    public String getPackageForToken(IBinder token) {
8086        synchronized(this) {
8087            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8088            if (r == null) {
8089                return null;
8090            }
8091            return r.packageName;
8092        }
8093    }
8094
8095    @Override
8096    public boolean isRootVoiceInteraction(IBinder token) {
8097        synchronized(this) {
8098            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8099            if (r == null) {
8100                return false;
8101            }
8102            return r.rootVoiceInteraction;
8103        }
8104    }
8105
8106    @Override
8107    public IIntentSender getIntentSender(int type,
8108            String packageName, IBinder token, String resultWho,
8109            int requestCode, Intent[] intents, String[] resolvedTypes,
8110            int flags, Bundle bOptions, int userId) {
8111        enforceNotIsolatedCaller("getIntentSender");
8112        // Refuse possible leaked file descriptors
8113        if (intents != null) {
8114            if (intents.length < 1) {
8115                throw new IllegalArgumentException("Intents array length must be >= 1");
8116            }
8117            for (int i=0; i<intents.length; i++) {
8118                Intent intent = intents[i];
8119                if (intent != null) {
8120                    if (intent.hasFileDescriptors()) {
8121                        throw new IllegalArgumentException("File descriptors passed in Intent");
8122                    }
8123                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
8124                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
8125                        throw new IllegalArgumentException(
8126                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
8127                    }
8128                    intents[i] = new Intent(intent);
8129                }
8130            }
8131            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
8132                throw new IllegalArgumentException(
8133                        "Intent array length does not match resolvedTypes length");
8134            }
8135        }
8136        if (bOptions != null) {
8137            if (bOptions.hasFileDescriptors()) {
8138                throw new IllegalArgumentException("File descriptors passed in options");
8139            }
8140        }
8141
8142        synchronized(this) {
8143            int callingUid = Binder.getCallingUid();
8144            int origUserId = userId;
8145            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8146                    type == ActivityManager.INTENT_SENDER_BROADCAST,
8147                    ALLOW_NON_FULL, "getIntentSender", null);
8148            if (origUserId == UserHandle.USER_CURRENT) {
8149                // We don't want to evaluate this until the pending intent is
8150                // actually executed.  However, we do want to always do the
8151                // security checking for it above.
8152                userId = UserHandle.USER_CURRENT;
8153            }
8154            try {
8155                if (callingUid != 0 && callingUid != SYSTEM_UID) {
8156                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
8157                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
8158                    if (!UserHandle.isSameApp(callingUid, uid)) {
8159                        String msg = "Permission Denial: getIntentSender() from pid="
8160                            + Binder.getCallingPid()
8161                            + ", uid=" + Binder.getCallingUid()
8162                            + ", (need uid=" + uid + ")"
8163                            + " is not allowed to send as package " + packageName;
8164                        Slog.w(TAG, msg);
8165                        throw new SecurityException(msg);
8166                    }
8167                }
8168
8169                return getIntentSenderLocked(type, packageName, callingUid, userId,
8170                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
8171
8172            } catch (RemoteException e) {
8173                throw new SecurityException(e);
8174            }
8175        }
8176    }
8177
8178    IIntentSender getIntentSenderLocked(int type, String packageName,
8179            int callingUid, int userId, IBinder token, String resultWho,
8180            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
8181            Bundle bOptions) {
8182        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
8183        ActivityRecord activity = null;
8184        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8185            activity = ActivityRecord.isInStackLocked(token);
8186            if (activity == null) {
8187                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
8188                return null;
8189            }
8190            if (activity.finishing) {
8191                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
8192                return null;
8193            }
8194        }
8195
8196        // We're going to be splicing together extras before sending, so we're
8197        // okay poking into any contained extras.
8198        if (intents != null) {
8199            for (int i = 0; i < intents.length; i++) {
8200                intents[i].setDefusable(true);
8201            }
8202        }
8203        Bundle.setDefusable(bOptions, true);
8204
8205        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
8206        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
8207        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
8208        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
8209                |PendingIntent.FLAG_UPDATE_CURRENT);
8210
8211        PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity,
8212                resultWho, requestCode, intents, resolvedTypes, flags,
8213                SafeActivityOptions.fromBundle(bOptions), userId);
8214        WeakReference<PendingIntentRecord> ref;
8215        ref = mIntentSenderRecords.get(key);
8216        PendingIntentRecord rec = ref != null ? ref.get() : null;
8217        if (rec != null) {
8218            if (!cancelCurrent) {
8219                if (updateCurrent) {
8220                    if (rec.key.requestIntent != null) {
8221                        rec.key.requestIntent.replaceExtras(intents != null ?
8222                                intents[intents.length - 1] : null);
8223                    }
8224                    if (intents != null) {
8225                        intents[intents.length-1] = rec.key.requestIntent;
8226                        rec.key.allIntents = intents;
8227                        rec.key.allResolvedTypes = resolvedTypes;
8228                    } else {
8229                        rec.key.allIntents = null;
8230                        rec.key.allResolvedTypes = null;
8231                    }
8232                }
8233                return rec;
8234            }
8235            makeIntentSenderCanceledLocked(rec);
8236            mIntentSenderRecords.remove(key);
8237        }
8238        if (noCreate) {
8239            return rec;
8240        }
8241        rec = new PendingIntentRecord(this, key, callingUid);
8242        mIntentSenderRecords.put(key, rec.ref);
8243        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
8244            if (activity.pendingResults == null) {
8245                activity.pendingResults
8246                        = new HashSet<WeakReference<PendingIntentRecord>>();
8247            }
8248            activity.pendingResults.add(rec.ref);
8249        }
8250        return rec;
8251    }
8252
8253    @Override
8254    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
8255            Intent intent, String resolvedType,
8256            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
8257        if (target instanceof PendingIntentRecord) {
8258            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
8259                    whitelistToken, finishedReceiver, requiredPermission, options);
8260        } else {
8261            if (intent == null) {
8262                // Weird case: someone has given us their own custom IIntentSender, and now
8263                // they have someone else trying to send to it but of course this isn't
8264                // really a PendingIntent, so there is no base Intent, and the caller isn't
8265                // supplying an Intent... but we never want to dispatch a null Intent to
8266                // a receiver, so um...  let's make something up.
8267                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
8268                intent = new Intent(Intent.ACTION_MAIN);
8269            }
8270            try {
8271                target.send(code, intent, resolvedType, whitelistToken, null,
8272                        requiredPermission, options);
8273            } catch (RemoteException e) {
8274            }
8275            // Platform code can rely on getting a result back when the send is done, but if
8276            // this intent sender is from outside of the system we can't rely on it doing that.
8277            // So instead we don't give it the result receiver, and instead just directly
8278            // report the finish immediately.
8279            if (finishedReceiver != null) {
8280                try {
8281                    finishedReceiver.performReceive(intent, 0,
8282                            null, null, false, false, UserHandle.getCallingUserId());
8283                } catch (RemoteException e) {
8284                }
8285            }
8286            return 0;
8287        }
8288    }
8289
8290    @Override
8291    public void cancelIntentSender(IIntentSender sender) {
8292        if (!(sender instanceof PendingIntentRecord)) {
8293            return;
8294        }
8295        synchronized(this) {
8296            PendingIntentRecord rec = (PendingIntentRecord)sender;
8297            try {
8298                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
8299                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
8300                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
8301                    String msg = "Permission Denial: cancelIntentSender() from pid="
8302                        + Binder.getCallingPid()
8303                        + ", uid=" + Binder.getCallingUid()
8304                        + " is not allowed to cancel package "
8305                        + rec.key.packageName;
8306                    Slog.w(TAG, msg);
8307                    throw new SecurityException(msg);
8308                }
8309            } catch (RemoteException e) {
8310                throw new SecurityException(e);
8311            }
8312            cancelIntentSenderLocked(rec, true);
8313        }
8314    }
8315
8316    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
8317        makeIntentSenderCanceledLocked(rec);
8318        mIntentSenderRecords.remove(rec.key);
8319        if (cleanActivity && rec.key.activity != null) {
8320            rec.key.activity.pendingResults.remove(rec.ref);
8321        }
8322    }
8323
8324    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
8325        rec.canceled = true;
8326        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
8327        if (callbacks != null) {
8328            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
8329        }
8330    }
8331
8332    @Override
8333    public String getPackageForIntentSender(IIntentSender pendingResult) {
8334        if (!(pendingResult instanceof PendingIntentRecord)) {
8335            return null;
8336        }
8337        try {
8338            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8339            return res.key.packageName;
8340        } catch (ClassCastException e) {
8341        }
8342        return null;
8343    }
8344
8345    @Override
8346    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
8347        if (!(sender instanceof PendingIntentRecord)) {
8348            return;
8349        }
8350        synchronized(this) {
8351            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
8352        }
8353    }
8354
8355    @Override
8356    public void unregisterIntentSenderCancelListener(IIntentSender sender,
8357            IResultReceiver receiver) {
8358        if (!(sender instanceof PendingIntentRecord)) {
8359            return;
8360        }
8361        synchronized(this) {
8362            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
8363        }
8364    }
8365
8366    @Override
8367    public int getUidForIntentSender(IIntentSender sender) {
8368        if (sender instanceof PendingIntentRecord) {
8369            try {
8370                PendingIntentRecord res = (PendingIntentRecord)sender;
8371                return res.uid;
8372            } catch (ClassCastException e) {
8373            }
8374        }
8375        return -1;
8376    }
8377
8378    @Override
8379    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
8380        if (!(pendingResult instanceof PendingIntentRecord)) {
8381            return false;
8382        }
8383        try {
8384            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8385            if (res.key.allIntents == null) {
8386                return false;
8387            }
8388            for (int i=0; i<res.key.allIntents.length; i++) {
8389                Intent intent = res.key.allIntents[i];
8390                if (intent.getPackage() != null && intent.getComponent() != null) {
8391                    return false;
8392                }
8393            }
8394            return true;
8395        } catch (ClassCastException e) {
8396        }
8397        return false;
8398    }
8399
8400    @Override
8401    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
8402        if (!(pendingResult instanceof PendingIntentRecord)) {
8403            return false;
8404        }
8405        try {
8406            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8407            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
8408                return true;
8409            }
8410            return false;
8411        } catch (ClassCastException e) {
8412        }
8413        return false;
8414    }
8415
8416    @Override
8417    public boolean isIntentSenderAForegroundService(IIntentSender pendingResult) {
8418        if (pendingResult instanceof PendingIntentRecord) {
8419            final PendingIntentRecord res = (PendingIntentRecord) pendingResult;
8420            return res.key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE;
8421        }
8422        return false;
8423    }
8424
8425    @Override
8426    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
8427        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
8428                "getIntentForIntentSender()");
8429        if (!(pendingResult instanceof PendingIntentRecord)) {
8430            return null;
8431        }
8432        try {
8433            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8434            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
8435        } catch (ClassCastException e) {
8436        }
8437        return null;
8438    }
8439
8440    @Override
8441    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
8442        if (!(pendingResult instanceof PendingIntentRecord)) {
8443            return null;
8444        }
8445        try {
8446            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
8447            synchronized (this) {
8448                return getTagForIntentSenderLocked(res, prefix);
8449            }
8450        } catch (ClassCastException e) {
8451        }
8452        return null;
8453    }
8454
8455    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
8456        final Intent intent = res.key.requestIntent;
8457        if (intent != null) {
8458            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
8459                    || res.lastTagPrefix.equals(prefix))) {
8460                return res.lastTag;
8461            }
8462            res.lastTagPrefix = prefix;
8463            final StringBuilder sb = new StringBuilder(128);
8464            if (prefix != null) {
8465                sb.append(prefix);
8466            }
8467            if (intent.getAction() != null) {
8468                sb.append(intent.getAction());
8469            } else if (intent.getComponent() != null) {
8470                intent.getComponent().appendShortString(sb);
8471            } else {
8472                sb.append("?");
8473            }
8474            return res.lastTag = sb.toString();
8475        }
8476        return null;
8477    }
8478
8479    @Override
8480    public void setProcessLimit(int max) {
8481        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8482                "setProcessLimit()");
8483        synchronized (this) {
8484            mConstants.setOverrideMaxCachedProcesses(max);
8485        }
8486        trimApplications();
8487    }
8488
8489    @Override
8490    public int getProcessLimit() {
8491        synchronized (this) {
8492            return mConstants.getOverrideMaxCachedProcesses();
8493        }
8494    }
8495
8496    void importanceTokenDied(ImportanceToken token) {
8497        synchronized (ActivityManagerService.this) {
8498            synchronized (mPidsSelfLocked) {
8499                ImportanceToken cur
8500                    = mImportantProcesses.get(token.pid);
8501                if (cur != token) {
8502                    return;
8503                }
8504                mImportantProcesses.remove(token.pid);
8505                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
8506                if (pr == null) {
8507                    return;
8508                }
8509                pr.forcingToImportant = null;
8510                updateProcessForegroundLocked(pr, false, false);
8511            }
8512            updateOomAdjLocked();
8513        }
8514    }
8515
8516    @Override
8517    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8518        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8519                "setProcessImportant()");
8520        synchronized(this) {
8521            boolean changed = false;
8522
8523            synchronized (mPidsSelfLocked) {
8524                ProcessRecord pr = mPidsSelfLocked.get(pid);
8525                if (pr == null && isForeground) {
8526                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8527                    return;
8528                }
8529                ImportanceToken oldToken = mImportantProcesses.get(pid);
8530                if (oldToken != null) {
8531                    oldToken.token.unlinkToDeath(oldToken, 0);
8532                    mImportantProcesses.remove(pid);
8533                    if (pr != null) {
8534                        pr.forcingToImportant = null;
8535                    }
8536                    changed = true;
8537                }
8538                if (isForeground && token != null) {
8539                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8540                        @Override
8541                        public void binderDied() {
8542                            importanceTokenDied(this);
8543                        }
8544                    };
8545                    try {
8546                        token.linkToDeath(newToken, 0);
8547                        mImportantProcesses.put(pid, newToken);
8548                        pr.forcingToImportant = newToken;
8549                        changed = true;
8550                    } catch (RemoteException e) {
8551                        // If the process died while doing this, we will later
8552                        // do the cleanup with the process death link.
8553                    }
8554                }
8555            }
8556
8557            if (changed) {
8558                updateOomAdjLocked();
8559            }
8560        }
8561    }
8562
8563    @Override
8564    public boolean isAppForeground(int uid) throws RemoteException {
8565        synchronized (this) {
8566            UidRecord uidRec = mActiveUids.get(uid);
8567            if (uidRec == null || uidRec.idle) {
8568                return false;
8569            }
8570            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8571        }
8572    }
8573
8574    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8575    // be guarded by permission checking.
8576    int getUidState(int uid) {
8577        synchronized (this) {
8578            return getUidStateLocked(uid);
8579        }
8580    }
8581
8582    int getUidStateLocked(int uid) {
8583        UidRecord uidRec = mActiveUids.get(uid);
8584        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8585    }
8586
8587    @Override
8588    public boolean isInMultiWindowMode(IBinder token) {
8589        final long origId = Binder.clearCallingIdentity();
8590        try {
8591            synchronized(this) {
8592                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8593                if (r == null) {
8594                    return false;
8595                }
8596                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8597                return r.inMultiWindowMode();
8598            }
8599        } finally {
8600            Binder.restoreCallingIdentity(origId);
8601        }
8602    }
8603
8604    @Override
8605    public boolean isInPictureInPictureMode(IBinder token) {
8606        final long origId = Binder.clearCallingIdentity();
8607        try {
8608            synchronized(this) {
8609                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8610            }
8611        } finally {
8612            Binder.restoreCallingIdentity(origId);
8613        }
8614    }
8615
8616    private boolean isInPictureInPictureMode(ActivityRecord r) {
8617        if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
8618                || r.getStack().isInStackLocked(r) == null) {
8619            return false;
8620        }
8621
8622        // If we are animating to fullscreen then we have already dispatched the PIP mode
8623        // changed, so we should reflect that check here as well.
8624        final PinnedActivityStack stack = r.getStack();
8625        final PinnedStackWindowController windowController = stack.getWindowContainerController();
8626        return !windowController.isAnimatingBoundsToFullscreen();
8627    }
8628
8629    @Override
8630    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8631        final long origId = Binder.clearCallingIdentity();
8632        try {
8633            synchronized(this) {
8634                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8635                        "enterPictureInPictureMode", token, params);
8636
8637                // If the activity is already in picture in picture mode, then just return early
8638                if (isInPictureInPictureMode(r)) {
8639                    return true;
8640                }
8641
8642                // Activity supports picture-in-picture, now check that we can enter PiP at this
8643                // point, if it is
8644                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8645                        false /* beforeStopping */)) {
8646                    return false;
8647                }
8648
8649                final Runnable enterPipRunnable = () -> {
8650                    // Only update the saved args from the args that are set
8651                    r.pictureInPictureArgs.copyOnlySet(params);
8652                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8653                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8654                    // Adjust the source bounds by the insets for the transition down
8655                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8656                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8657                            "enterPictureInPictureMode");
8658                    final PinnedActivityStack stack = r.getStack();
8659                    stack.setPictureInPictureAspectRatio(aspectRatio);
8660                    stack.setPictureInPictureActions(actions);
8661                    MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
8662                            r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
8663                    logPictureInPictureArgs(params);
8664                };
8665
8666                if (isKeyguardLocked()) {
8667                    // If the keyguard is showing or occluded, then try and dismiss it before
8668                    // entering picture-in-picture (this will prompt the user to authenticate if the
8669                    // device is currently locked).
8670                    try {
8671                        dismissKeyguard(token, new KeyguardDismissCallback() {
8672                            @Override
8673                            public void onDismissSucceeded() throws RemoteException {
8674                                mHandler.post(enterPipRunnable);
8675                            }
8676                        }, null /* message */);
8677                    } catch (RemoteException e) {
8678                        // Local call
8679                    }
8680                } else {
8681                    // Enter picture in picture immediately otherwise
8682                    enterPipRunnable.run();
8683                }
8684                return true;
8685            }
8686        } finally {
8687            Binder.restoreCallingIdentity(origId);
8688        }
8689    }
8690
8691    @Override
8692    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8693        final long origId = Binder.clearCallingIdentity();
8694        try {
8695            synchronized(this) {
8696                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8697                        "setPictureInPictureParams", token, params);
8698
8699                // Only update the saved args from the args that are set
8700                r.pictureInPictureArgs.copyOnlySet(params);
8701                if (r.inPinnedWindowingMode()) {
8702                    // If the activity is already in picture-in-picture, update the pinned stack now
8703                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8704                    // be used the next time the activity enters PiP
8705                    final PinnedActivityStack stack = r.getStack();
8706                    if (!stack.isAnimatingBoundsToFullscreen()) {
8707                        stack.setPictureInPictureAspectRatio(
8708                                r.pictureInPictureArgs.getAspectRatio());
8709                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8710                    }
8711                }
8712                logPictureInPictureArgs(params);
8713            }
8714        } finally {
8715            Binder.restoreCallingIdentity(origId);
8716        }
8717    }
8718
8719    @Override
8720    public int getMaxNumPictureInPictureActions(IBinder token) {
8721        // Currently, this is a static constant, but later, we may change this to be dependent on
8722        // the context of the activity
8723        return 3;
8724    }
8725
8726    private void logPictureInPictureArgs(PictureInPictureParams params) {
8727        if (params.hasSetActions()) {
8728            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8729                    params.getActions().size());
8730        }
8731        if (params.hasSetAspectRatio()) {
8732            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8733            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8734            MetricsLogger.action(lm);
8735        }
8736    }
8737
8738    /**
8739     * Checks the state of the system and the activity associated with the given {@param token} to
8740     * verify that picture-in-picture is supported for that activity.
8741     *
8742     * @return the activity record for the given {@param token} if all the checks pass.
8743     */
8744    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8745            IBinder token, PictureInPictureParams params) {
8746        if (!mSupportsPictureInPicture) {
8747            throw new IllegalStateException(caller
8748                    + ": Device doesn't support picture-in-picture mode.");
8749        }
8750
8751        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8752        if (r == null) {
8753            throw new IllegalStateException(caller
8754                    + ": Can't find activity for token=" + token);
8755        }
8756
8757        if (!r.supportsPictureInPicture()) {
8758            throw new IllegalStateException(caller
8759                    + ": Current activity does not support picture-in-picture.");
8760        }
8761
8762        if (params.hasSetAspectRatio()
8763                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8764                        params.getAspectRatio())) {
8765            final float minAspectRatio = mContext.getResources().getFloat(
8766                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8767            final float maxAspectRatio = mContext.getResources().getFloat(
8768                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8769            throw new IllegalArgumentException(String.format(caller
8770                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8771                            minAspectRatio, maxAspectRatio));
8772        }
8773
8774        // Truncate the number of actions if necessary
8775        params.truncateActions(getMaxNumPictureInPictureActions(token));
8776
8777        return r;
8778    }
8779
8780    // =========================================================
8781    // PROCESS INFO
8782    // =========================================================
8783
8784    static class ProcessInfoService extends IProcessInfoService.Stub {
8785        final ActivityManagerService mActivityManagerService;
8786        ProcessInfoService(ActivityManagerService activityManagerService) {
8787            mActivityManagerService = activityManagerService;
8788        }
8789
8790        @Override
8791        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8792            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8793                    /*in*/ pids, /*out*/ states, null);
8794        }
8795
8796        @Override
8797        public void getProcessStatesAndOomScoresFromPids(
8798                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8799            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8800                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8801        }
8802    }
8803
8804    /**
8805     * For each PID in the given input array, write the current process state
8806     * for that process into the states array, or -1 to indicate that no
8807     * process with the given PID exists. If scores array is provided, write
8808     * the oom score for the process into the scores array, with INVALID_ADJ
8809     * indicating the PID doesn't exist.
8810     */
8811    public void getProcessStatesAndOomScoresForPIDs(
8812            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8813        if (scores != null) {
8814            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8815                    "getProcessStatesAndOomScoresForPIDs()");
8816        }
8817
8818        if (pids == null) {
8819            throw new NullPointerException("pids");
8820        } else if (states == null) {
8821            throw new NullPointerException("states");
8822        } else if (pids.length != states.length) {
8823            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8824        } else if (scores != null && pids.length != scores.length) {
8825            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8826        }
8827
8828        synchronized (mPidsSelfLocked) {
8829            for (int i = 0; i < pids.length; i++) {
8830                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8831                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8832                        pr.curProcState;
8833                if (scores != null) {
8834                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8835                }
8836            }
8837        }
8838    }
8839
8840    // =========================================================
8841    // PERMISSIONS
8842    // =========================================================
8843
8844    static class PermissionController extends IPermissionController.Stub {
8845        ActivityManagerService mActivityManagerService;
8846        PermissionController(ActivityManagerService activityManagerService) {
8847            mActivityManagerService = activityManagerService;
8848        }
8849
8850        @Override
8851        public boolean checkPermission(String permission, int pid, int uid) {
8852            return mActivityManagerService.checkPermission(permission, pid,
8853                    uid) == PackageManager.PERMISSION_GRANTED;
8854        }
8855
8856        @Override
8857        public String[] getPackagesForUid(int uid) {
8858            return mActivityManagerService.mContext.getPackageManager()
8859                    .getPackagesForUid(uid);
8860        }
8861
8862        @Override
8863        public boolean isRuntimePermission(String permission) {
8864            try {
8865                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8866                        .getPermissionInfo(permission, 0);
8867                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8868                        == PermissionInfo.PROTECTION_DANGEROUS;
8869            } catch (NameNotFoundException nnfe) {
8870                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8871            }
8872            return false;
8873        }
8874
8875        @Override
8876        public int getPackageUid(String packageName, int flags) {
8877            try {
8878                return mActivityManagerService.mContext.getPackageManager()
8879                        .getPackageUid(packageName, flags);
8880            } catch (NameNotFoundException nnfe) {
8881                return -1;
8882            }
8883        }
8884    }
8885
8886    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8887        @Override
8888        public int checkComponentPermission(String permission, int pid, int uid,
8889                int owningUid, boolean exported) {
8890            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8891                    owningUid, exported);
8892        }
8893
8894        @Override
8895        public Object getAMSLock() {
8896            return ActivityManagerService.this;
8897        }
8898    }
8899
8900    int checkComponentPermission(String permission, int pid, int uid,
8901            int owningUid, boolean exported) {
8902        if (pid == MY_PID) {
8903            return PackageManager.PERMISSION_GRANTED;
8904        }
8905        return ActivityManager.checkComponentPermission(permission, uid,
8906                owningUid, exported);
8907    }
8908
8909    /**
8910     * As the only public entry point for permissions checking, this method
8911     * can enforce the semantic that requesting a check on a null global
8912     * permission is automatically denied.  (Internally a null permission
8913     * string is used when calling {@link #checkComponentPermission} in cases
8914     * when only uid-based security is needed.)
8915     *
8916     * This can be called with or without the global lock held.
8917     */
8918    @Override
8919    public int checkPermission(String permission, int pid, int uid) {
8920        if (permission == null) {
8921            return PackageManager.PERMISSION_DENIED;
8922        }
8923        return checkComponentPermission(permission, pid, uid, -1, true);
8924    }
8925
8926    @Override
8927    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8928        if (permission == null) {
8929            return PackageManager.PERMISSION_DENIED;
8930        }
8931
8932        // We might be performing an operation on behalf of an indirect binder
8933        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8934        // client identity accordingly before proceeding.
8935        Identity tlsIdentity = sCallerIdentity.get();
8936        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8937            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8938                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8939            uid = tlsIdentity.uid;
8940            pid = tlsIdentity.pid;
8941        }
8942
8943        return checkComponentPermission(permission, pid, uid, -1, true);
8944    }
8945
8946    /**
8947     * Binder IPC calls go through the public entry point.
8948     * This can be called with or without the global lock held.
8949     */
8950    int checkCallingPermission(String permission) {
8951        return checkPermission(permission,
8952                Binder.getCallingPid(),
8953                UserHandle.getAppId(Binder.getCallingUid()));
8954    }
8955
8956    /**
8957     * This can be called with or without the global lock held.
8958     */
8959    void enforceCallingPermission(String permission, String func) {
8960        if (checkCallingPermission(permission)
8961                == PackageManager.PERMISSION_GRANTED) {
8962            return;
8963        }
8964
8965        String msg = "Permission Denial: " + func + " from pid="
8966                + Binder.getCallingPid()
8967                + ", uid=" + Binder.getCallingUid()
8968                + " requires " + permission;
8969        Slog.w(TAG, msg);
8970        throw new SecurityException(msg);
8971    }
8972
8973    /**
8974     * This can be called with or without the global lock held.
8975     */
8976    void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
8977        if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
8978            enforceCallingPermission(permission, func);
8979        }
8980    }
8981
8982    /**
8983     * Determine if UID is holding permissions required to access {@link Uri} in
8984     * the given {@link ProviderInfo}. Final permission checking is always done
8985     * in {@link ContentProvider}.
8986     */
8987    private final boolean checkHoldingPermissionsLocked(
8988            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8989        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8990                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8991        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8992            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8993                    != PERMISSION_GRANTED) {
8994                return false;
8995            }
8996        }
8997        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8998    }
8999
9000    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
9001            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
9002        if (pi.applicationInfo.uid == uid) {
9003            return true;
9004        } else if (!pi.exported) {
9005            return false;
9006        }
9007
9008        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
9009        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
9010        try {
9011            // check if target holds top-level <provider> permissions
9012            if (!readMet && pi.readPermission != null && considerUidPermissions
9013                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
9014                readMet = true;
9015            }
9016            if (!writeMet && pi.writePermission != null && considerUidPermissions
9017                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
9018                writeMet = true;
9019            }
9020
9021            // track if unprotected read/write is allowed; any denied
9022            // <path-permission> below removes this ability
9023            boolean allowDefaultRead = pi.readPermission == null;
9024            boolean allowDefaultWrite = pi.writePermission == null;
9025
9026            // check if target holds any <path-permission> that match uri
9027            final PathPermission[] pps = pi.pathPermissions;
9028            if (pps != null) {
9029                final String path = grantUri.uri.getPath();
9030                int i = pps.length;
9031                while (i > 0 && (!readMet || !writeMet)) {
9032                    i--;
9033                    PathPermission pp = pps[i];
9034                    if (pp.match(path)) {
9035                        if (!readMet) {
9036                            final String pprperm = pp.getReadPermission();
9037                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9038                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
9039                                    + ": match=" + pp.match(path)
9040                                    + " check=" + pm.checkUidPermission(pprperm, uid));
9041                            if (pprperm != null) {
9042                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
9043                                        == PERMISSION_GRANTED) {
9044                                    readMet = true;
9045                                } else {
9046                                    allowDefaultRead = false;
9047                                }
9048                            }
9049                        }
9050                        if (!writeMet) {
9051                            final String ppwperm = pp.getWritePermission();
9052                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9053                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
9054                                    + ": match=" + pp.match(path)
9055                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
9056                            if (ppwperm != null) {
9057                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
9058                                        == PERMISSION_GRANTED) {
9059                                    writeMet = true;
9060                                } else {
9061                                    allowDefaultWrite = false;
9062                                }
9063                            }
9064                        }
9065                    }
9066                }
9067            }
9068
9069            // grant unprotected <provider> read/write, if not blocked by
9070            // <path-permission> above
9071            if (allowDefaultRead) readMet = true;
9072            if (allowDefaultWrite) writeMet = true;
9073
9074        } catch (RemoteException e) {
9075            return false;
9076        }
9077
9078        return readMet && writeMet;
9079    }
9080
9081    public boolean isAppStartModeDisabled(int uid, String packageName) {
9082        synchronized (this) {
9083            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
9084                    == ActivityManager.APP_START_MODE_DISABLED;
9085        }
9086    }
9087
9088    // Unified app-op and target sdk check
9089    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9090        // Apps that target O+ are always subject to background check
9091        if (packageTargetSdk >= Build.VERSION_CODES.O) {
9092            if (DEBUG_BACKGROUND_CHECK) {
9093                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
9094            }
9095            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9096        }
9097        // ...and legacy apps get an AppOp check
9098        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
9099                uid, packageName);
9100        if (DEBUG_BACKGROUND_CHECK) {
9101            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
9102        }
9103        switch (appop) {
9104            case AppOpsManager.MODE_ALLOWED:
9105                // If force-background-check is enabled, restrict all apps that aren't whitelisted.
9106                if (mForceBackgroundCheck &&
9107                        !UserHandle.isCore(uid) &&
9108                        !isOnDeviceIdleWhitelistLocked(uid)) {
9109                    if (DEBUG_BACKGROUND_CHECK) {
9110                        Slog.i(TAG, "Force background check: " +
9111                                uid + "/" + packageName + " restricted");
9112                    }
9113                    return ActivityManager.APP_START_MODE_DELAYED;
9114                }
9115                return ActivityManager.APP_START_MODE_NORMAL;
9116            case AppOpsManager.MODE_IGNORED:
9117                return ActivityManager.APP_START_MODE_DELAYED;
9118            default:
9119                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
9120        }
9121    }
9122
9123    // Service launch is available to apps with run-in-background exemptions but
9124    // some other background operations are not.  If we're doing a check
9125    // of service-launch policy, allow those callers to proceed unrestricted.
9126    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
9127        // Persistent app?
9128        if (mPackageManagerInt.isPackagePersistent(packageName)) {
9129            if (DEBUG_BACKGROUND_CHECK) {
9130                Slog.i(TAG, "App " + uid + "/" + packageName
9131                        + " is persistent; not restricted in background");
9132            }
9133            return ActivityManager.APP_START_MODE_NORMAL;
9134        }
9135
9136        // Non-persistent but background whitelisted?
9137        if (uidOnBackgroundWhitelist(uid)) {
9138            if (DEBUG_BACKGROUND_CHECK) {
9139                Slog.i(TAG, "App " + uid + "/" + packageName
9140                        + " on background whitelist; not restricted in background");
9141            }
9142            return ActivityManager.APP_START_MODE_NORMAL;
9143        }
9144
9145        // Is this app on the battery whitelist?
9146        if (isOnDeviceIdleWhitelistLocked(uid)) {
9147            if (DEBUG_BACKGROUND_CHECK) {
9148                Slog.i(TAG, "App " + uid + "/" + packageName
9149                        + " on idle whitelist; not restricted in background");
9150            }
9151            return ActivityManager.APP_START_MODE_NORMAL;
9152        }
9153
9154        // None of the service-policy criteria apply, so we apply the common criteria
9155        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
9156    }
9157
9158    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
9159            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
9160        UidRecord uidRec = mActiveUids.get(uid);
9161        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
9162                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
9163                + (uidRec != null ? uidRec.idle : false));
9164        if (uidRec == null || alwaysRestrict || uidRec.idle) {
9165            boolean ephemeral;
9166            if (uidRec == null) {
9167                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
9168                        UserHandle.getUserId(uid), packageName);
9169            } else {
9170                ephemeral = uidRec.ephemeral;
9171            }
9172
9173            if (ephemeral) {
9174                // We are hard-core about ephemeral apps not running in the background.
9175                return ActivityManager.APP_START_MODE_DISABLED;
9176            } else {
9177                if (disabledOnly) {
9178                    // The caller is only interested in whether app starts are completely
9179                    // disabled for the given package (that is, it is an instant app).  So
9180                    // we don't need to go further, which is all just seeing if we should
9181                    // apply a "delayed" mode for a regular app.
9182                    return ActivityManager.APP_START_MODE_NORMAL;
9183                }
9184                final int startMode = (alwaysRestrict)
9185                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
9186                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
9187                                packageTargetSdk);
9188                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
9189                        + " pkg=" + packageName + " startMode=" + startMode
9190                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
9191                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
9192                    // This is an old app that has been forced into a "compatible as possible"
9193                    // mode of background check.  To increase compatibility, we will allow other
9194                    // foreground apps to cause its services to start.
9195                    if (callingPid >= 0) {
9196                        ProcessRecord proc;
9197                        synchronized (mPidsSelfLocked) {
9198                            proc = mPidsSelfLocked.get(callingPid);
9199                        }
9200                        if (proc != null &&
9201                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
9202                            // Whoever is instigating this is in the foreground, so we will allow it
9203                            // to go through.
9204                            return ActivityManager.APP_START_MODE_NORMAL;
9205                        }
9206                    }
9207                }
9208                return startMode;
9209            }
9210        }
9211        return ActivityManager.APP_START_MODE_NORMAL;
9212    }
9213
9214    /**
9215     * @return whether a UID is in the system, user or temp doze whitelist.
9216     */
9217    boolean isOnDeviceIdleWhitelistLocked(int uid) {
9218        final int appId = UserHandle.getAppId(uid);
9219        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
9220                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
9221                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
9222    }
9223
9224    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
9225        ProviderInfo pi = null;
9226        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
9227        if (cpr != null) {
9228            pi = cpr.info;
9229        } else {
9230            try {
9231                pi = AppGlobals.getPackageManager().resolveContentProvider(
9232                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
9233                        userHandle);
9234            } catch (RemoteException ex) {
9235            }
9236        }
9237        return pi;
9238    }
9239
9240    void grantEphemeralAccessLocked(int userId, Intent intent,
9241            int targetAppId, int ephemeralAppId) {
9242        getPackageManagerInternalLocked().
9243                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
9244    }
9245
9246    @GuardedBy("this")
9247    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
9248        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9249        if (targetUris != null) {
9250            return targetUris.get(grantUri);
9251        }
9252        return null;
9253    }
9254
9255    @GuardedBy("this")
9256    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
9257            String targetPkg, int targetUid, GrantUri grantUri) {
9258        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
9259        if (targetUris == null) {
9260            targetUris = Maps.newArrayMap();
9261            mGrantedUriPermissions.put(targetUid, targetUris);
9262        }
9263
9264        UriPermission perm = targetUris.get(grantUri);
9265        if (perm == null) {
9266            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
9267            targetUris.put(grantUri, perm);
9268        }
9269
9270        return perm;
9271    }
9272
9273    @GuardedBy("this")
9274    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
9275            final int modeFlags) {
9276        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
9277        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
9278                : UriPermission.STRENGTH_OWNED;
9279
9280        // Root gets to do everything.
9281        if (uid == 0) {
9282            return true;
9283        }
9284
9285        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9286        if (perms == null) return false;
9287
9288        // First look for exact match
9289        final UriPermission exactPerm = perms.get(grantUri);
9290        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
9291            return true;
9292        }
9293
9294        // No exact match, look for prefixes
9295        final int N = perms.size();
9296        for (int i = 0; i < N; i++) {
9297            final UriPermission perm = perms.valueAt(i);
9298            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
9299                    && perm.getStrength(modeFlags) >= minStrength) {
9300                return true;
9301            }
9302        }
9303
9304        return false;
9305    }
9306
9307    /**
9308     * @param uri This uri must NOT contain an embedded userId.
9309     * @param userId The userId in which the uri is to be resolved.
9310     */
9311    @Override
9312    public int checkUriPermission(Uri uri, int pid, int uid,
9313            final int modeFlags, int userId, IBinder callerToken) {
9314        enforceNotIsolatedCaller("checkUriPermission");
9315
9316        // Another redirected-binder-call permissions check as in
9317        // {@link checkPermissionWithToken}.
9318        Identity tlsIdentity = sCallerIdentity.get();
9319        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
9320            uid = tlsIdentity.uid;
9321            pid = tlsIdentity.pid;
9322        }
9323
9324        // Our own process gets to do everything.
9325        if (pid == MY_PID) {
9326            return PackageManager.PERMISSION_GRANTED;
9327        }
9328        synchronized (this) {
9329            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
9330                    ? PackageManager.PERMISSION_GRANTED
9331                    : PackageManager.PERMISSION_DENIED;
9332        }
9333    }
9334
9335    /**
9336     * Check if the targetPkg can be granted permission to access uri by
9337     * the callingUid using the given modeFlags.  Throws a security exception
9338     * if callingUid is not allowed to do this.  Returns the uid of the target
9339     * if the URI permission grant should be performed; returns -1 if it is not
9340     * needed (for example targetPkg already has permission to access the URI).
9341     * If you already know the uid of the target, you can supply it in
9342     * lastTargetUid else set that to -1.
9343     */
9344    @GuardedBy("this")
9345    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9346            final int modeFlags, int lastTargetUid) {
9347        if (!Intent.isAccessUriMode(modeFlags)) {
9348            return -1;
9349        }
9350
9351        if (targetPkg != null) {
9352            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9353                    "Checking grant " + targetPkg + " permission to " + grantUri);
9354        }
9355
9356        final IPackageManager pm = AppGlobals.getPackageManager();
9357
9358        // If this is not a content: uri, we can't do anything with it.
9359        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
9360            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9361                    "Can't grant URI permission for non-content URI: " + grantUri);
9362            return -1;
9363        }
9364
9365        // Bail early if system is trying to hand out permissions directly; it
9366        // must always grant permissions on behalf of someone explicit.
9367        final int callingAppId = UserHandle.getAppId(callingUid);
9368        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
9369            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
9370                // Exempted authority for
9371                // 1. cropping user photos and sharing a generated license html
9372                //    file in Settings app
9373                // 2. sharing a generated license html file in TvSettings app
9374            } else {
9375                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
9376                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
9377                return -1;
9378            }
9379        }
9380
9381        final String authority = grantUri.uri.getAuthority();
9382        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9383                MATCH_DEBUG_TRIAGED_MISSING);
9384        if (pi == null) {
9385            Slog.w(TAG, "No content provider found for permission check: " +
9386                    grantUri.uri.toSafeString());
9387            return -1;
9388        }
9389
9390        int targetUid = lastTargetUid;
9391        if (targetUid < 0 && targetPkg != null) {
9392            try {
9393                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9394                        UserHandle.getUserId(callingUid));
9395                if (targetUid < 0) {
9396                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9397                            "Can't grant URI permission no uid for: " + targetPkg);
9398                    return -1;
9399                }
9400            } catch (RemoteException ex) {
9401                return -1;
9402            }
9403        }
9404
9405        // If we're extending a persistable grant, then we always need to create
9406        // the grant data structure so that take/release APIs work
9407        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
9408            return targetUid;
9409        }
9410
9411        if (targetUid >= 0) {
9412            // First...  does the target actually need this permission?
9413            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
9414                // No need to grant the target this permission.
9415                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9416                        "Target " + targetPkg + " already has full permission to " + grantUri);
9417                return -1;
9418            }
9419        } else {
9420            // First...  there is no target package, so can anyone access it?
9421            boolean allowed = pi.exported;
9422            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
9423                if (pi.readPermission != null) {
9424                    allowed = false;
9425                }
9426            }
9427            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
9428                if (pi.writePermission != null) {
9429                    allowed = false;
9430                }
9431            }
9432            if (allowed) {
9433                return -1;
9434            }
9435        }
9436
9437        /* There is a special cross user grant if:
9438         * - The target is on another user.
9439         * - Apps on the current user can access the uri without any uid permissions.
9440         * In this case, we grant a uri permission, even if the ContentProvider does not normally
9441         * grant uri permissions.
9442         */
9443        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
9444                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
9445                modeFlags, false /*without considering the uid permissions*/);
9446
9447        // Second...  is the provider allowing granting of URI permissions?
9448        if (!specialCrossUserGrant) {
9449            if (!pi.grantUriPermissions) {
9450                throw new SecurityException("Provider " + pi.packageName
9451                        + "/" + pi.name
9452                        + " does not allow granting of Uri permissions (uri "
9453                        + grantUri + ")");
9454            }
9455            if (pi.uriPermissionPatterns != null) {
9456                final int N = pi.uriPermissionPatterns.length;
9457                boolean allowed = false;
9458                for (int i=0; i<N; i++) {
9459                    if (pi.uriPermissionPatterns[i] != null
9460                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
9461                        allowed = true;
9462                        break;
9463                    }
9464                }
9465                if (!allowed) {
9466                    throw new SecurityException("Provider " + pi.packageName
9467                            + "/" + pi.name
9468                            + " does not allow granting of permission to path of Uri "
9469                            + grantUri);
9470                }
9471            }
9472        }
9473
9474        // Third...  does the caller itself have permission to access
9475        // this uri?
9476        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9477            // Require they hold a strong enough Uri permission
9478            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
9479                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
9480                    throw new SecurityException(
9481                            "UID " + callingUid + " does not have permission to " + grantUri
9482                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
9483                                    + "or related APIs");
9484                } else {
9485                    throw new SecurityException(
9486                            "UID " + callingUid + " does not have permission to " + grantUri);
9487                }
9488            }
9489        }
9490        return targetUid;
9491    }
9492
9493    /**
9494     * @param uri This uri must NOT contain an embedded userId.
9495     * @param userId The userId in which the uri is to be resolved.
9496     */
9497    @Override
9498    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
9499            final int modeFlags, int userId) {
9500        enforceNotIsolatedCaller("checkGrantUriPermission");
9501        synchronized(this) {
9502            return checkGrantUriPermissionLocked(callingUid, targetPkg,
9503                    new GrantUri(userId, uri, false), modeFlags, -1);
9504        }
9505    }
9506
9507    @GuardedBy("this")
9508    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
9509            final int modeFlags, UriPermissionOwner owner) {
9510        if (!Intent.isAccessUriMode(modeFlags)) {
9511            return;
9512        }
9513
9514        // So here we are: the caller has the assumed permission
9515        // to the uri, and the target doesn't.  Let's now give this to
9516        // the target.
9517
9518        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9519                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
9520
9521        final String authority = grantUri.uri.getAuthority();
9522        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9523                MATCH_DEBUG_TRIAGED_MISSING);
9524        if (pi == null) {
9525            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
9526            return;
9527        }
9528
9529        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
9530            grantUri.prefix = true;
9531        }
9532        final UriPermission perm = findOrCreateUriPermissionLocked(
9533                pi.packageName, targetPkg, targetUid, grantUri);
9534        perm.grantModes(modeFlags, owner);
9535    }
9536
9537    @GuardedBy("this")
9538    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9539            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9540        if (targetPkg == null) {
9541            throw new NullPointerException("targetPkg");
9542        }
9543        int targetUid;
9544        final IPackageManager pm = AppGlobals.getPackageManager();
9545        try {
9546            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9547        } catch (RemoteException ex) {
9548            return;
9549        }
9550
9551        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9552                targetUid);
9553        if (targetUid < 0) {
9554            return;
9555        }
9556
9557        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9558                owner);
9559    }
9560
9561    static class NeededUriGrants extends ArrayList<GrantUri> {
9562        final String targetPkg;
9563        final int targetUid;
9564        final int flags;
9565
9566        NeededUriGrants(String targetPkg, int targetUid, int flags) {
9567            this.targetPkg = targetPkg;
9568            this.targetUid = targetUid;
9569            this.flags = flags;
9570        }
9571
9572        void writeToProto(ProtoOutputStream proto, long fieldId) {
9573            long token = proto.start(fieldId);
9574            proto.write(NeededUriGrantsProto.TARGET_PACKAGE, targetPkg);
9575            proto.write(NeededUriGrantsProto.TARGET_UID, targetUid);
9576            proto.write(NeededUriGrantsProto.FLAGS, flags);
9577
9578            final int N = this.size();
9579            for (int i=0; i<N; i++) {
9580                this.get(i).writeToProto(proto, NeededUriGrantsProto.GRANTS);
9581            }
9582            proto.end(token);
9583        }
9584    }
9585
9586    /**
9587     * Like checkGrantUriPermissionLocked, but takes an Intent.
9588     */
9589    @GuardedBy("this")
9590    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9591            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9592        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9593                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9594                + " clip=" + (intent != null ? intent.getClipData() : null)
9595                + " from " + intent + "; flags=0x"
9596                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9597
9598        if (targetPkg == null) {
9599            throw new NullPointerException("targetPkg");
9600        }
9601
9602        if (intent == null) {
9603            return null;
9604        }
9605        Uri data = intent.getData();
9606        ClipData clip = intent.getClipData();
9607        if (data == null && clip == null) {
9608            return null;
9609        }
9610        // Default userId for uris in the intent (if they don't specify it themselves)
9611        int contentUserHint = intent.getContentUserHint();
9612        if (contentUserHint == UserHandle.USER_CURRENT) {
9613            contentUserHint = UserHandle.getUserId(callingUid);
9614        }
9615        final IPackageManager pm = AppGlobals.getPackageManager();
9616        int targetUid;
9617        if (needed != null) {
9618            targetUid = needed.targetUid;
9619        } else {
9620            try {
9621                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9622                        targetUserId);
9623            } catch (RemoteException ex) {
9624                return null;
9625            }
9626            if (targetUid < 0) {
9627                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9628                        "Can't grant URI permission no uid for: " + targetPkg
9629                        + " on user " + targetUserId);
9630                return null;
9631            }
9632        }
9633        if (data != null) {
9634            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9635            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9636                    targetUid);
9637            if (targetUid > 0) {
9638                if (needed == null) {
9639                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
9640                }
9641                needed.add(grantUri);
9642            }
9643        }
9644        if (clip != null) {
9645            for (int i=0; i<clip.getItemCount(); i++) {
9646                Uri uri = clip.getItemAt(i).getUri();
9647                if (uri != null) {
9648                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9649                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9650                            targetUid);
9651                    if (targetUid > 0) {
9652                        if (needed == null) {
9653                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
9654                        }
9655                        needed.add(grantUri);
9656                    }
9657                } else {
9658                    Intent clipIntent = clip.getItemAt(i).getIntent();
9659                    if (clipIntent != null) {
9660                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9661                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9662                        if (newNeeded != null) {
9663                            needed = newNeeded;
9664                        }
9665                    }
9666                }
9667            }
9668        }
9669
9670        return needed;
9671    }
9672
9673    /**
9674     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9675     */
9676    @GuardedBy("this")
9677    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9678            UriPermissionOwner owner) {
9679        if (needed != null) {
9680            for (int i=0; i<needed.size(); i++) {
9681                GrantUri grantUri = needed.get(i);
9682                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9683                        grantUri, needed.flags, owner);
9684            }
9685        }
9686    }
9687
9688    @GuardedBy("this")
9689    void grantUriPermissionFromIntentLocked(int callingUid,
9690            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9691        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9692                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9693        if (needed == null) {
9694            return;
9695        }
9696
9697        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9698    }
9699
9700    /**
9701     * @param uri This uri must NOT contain an embedded userId.
9702     * @param userId The userId in which the uri is to be resolved.
9703     */
9704    @Override
9705    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9706            final int modeFlags, int userId) {
9707        enforceNotIsolatedCaller("grantUriPermission");
9708        GrantUri grantUri = new GrantUri(userId, uri, false);
9709        synchronized(this) {
9710            final ProcessRecord r = getRecordForAppLocked(caller);
9711            if (r == null) {
9712                throw new SecurityException("Unable to find app for caller "
9713                        + caller
9714                        + " when granting permission to uri " + grantUri);
9715            }
9716            if (targetPkg == null) {
9717                throw new IllegalArgumentException("null target");
9718            }
9719            if (grantUri == null) {
9720                throw new IllegalArgumentException("null uri");
9721            }
9722
9723            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9724                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9725                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9726                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9727
9728            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9729                    UserHandle.getUserId(r.uid));
9730        }
9731    }
9732
9733    @GuardedBy("this")
9734    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9735        if (perm.modeFlags == 0) {
9736            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9737                    perm.targetUid);
9738            if (perms != null) {
9739                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9740                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9741
9742                perms.remove(perm.uri);
9743                if (perms.isEmpty()) {
9744                    mGrantedUriPermissions.remove(perm.targetUid);
9745                }
9746            }
9747        }
9748    }
9749
9750    @GuardedBy("this")
9751    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9752            final int modeFlags) {
9753        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9754                "Revoking all granted permissions to " + grantUri);
9755
9756        final IPackageManager pm = AppGlobals.getPackageManager();
9757        final String authority = grantUri.uri.getAuthority();
9758        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9759                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9760        if (pi == null) {
9761            Slog.w(TAG, "No content provider found for permission revoke: "
9762                    + grantUri.toSafeString());
9763            return;
9764        }
9765
9766        // Does the caller have this permission on the URI?
9767        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9768            // If they don't have direct access to the URI, then revoke any
9769            // ownerless URI permissions that have been granted to them.
9770            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9771            if (perms != null) {
9772                boolean persistChanged = false;
9773                for (int i = perms.size()-1; i >= 0; i--) {
9774                    final UriPermission perm = perms.valueAt(i);
9775                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9776                        continue;
9777                    }
9778                    if (perm.uri.sourceUserId == grantUri.sourceUserId
9779                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9780                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9781                                "Revoking non-owned " + perm.targetUid
9782                                + " permission to " + perm.uri);
9783                        persistChanged |= perm.revokeModes(
9784                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9785                        if (perm.modeFlags == 0) {
9786                            perms.removeAt(i);
9787                        }
9788                    }
9789                }
9790                if (perms.isEmpty()) {
9791                    mGrantedUriPermissions.remove(callingUid);
9792                }
9793                if (persistChanged) {
9794                    schedulePersistUriGrants();
9795                }
9796            }
9797            return;
9798        }
9799
9800        boolean persistChanged = false;
9801
9802        // Go through all of the permissions and remove any that match.
9803        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9804            final int targetUid = mGrantedUriPermissions.keyAt(i);
9805            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9806
9807            for (int j = perms.size()-1; j >= 0; j--) {
9808                final UriPermission perm = perms.valueAt(j);
9809                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9810                    continue;
9811                }
9812                if (perm.uri.sourceUserId == grantUri.sourceUserId
9813                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9814                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9815                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9816                    persistChanged |= perm.revokeModes(
9817                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9818                            targetPackage == null);
9819                    if (perm.modeFlags == 0) {
9820                        perms.removeAt(j);
9821                    }
9822                }
9823            }
9824
9825            if (perms.isEmpty()) {
9826                mGrantedUriPermissions.removeAt(i);
9827            }
9828        }
9829
9830        if (persistChanged) {
9831            schedulePersistUriGrants();
9832        }
9833    }
9834
9835    /**
9836     * @param uri This uri must NOT contain an embedded userId.
9837     * @param userId The userId in which the uri is to be resolved.
9838     */
9839    @Override
9840    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9841            final int modeFlags, int userId) {
9842        enforceNotIsolatedCaller("revokeUriPermission");
9843        synchronized(this) {
9844            final ProcessRecord r = getRecordForAppLocked(caller);
9845            if (r == null) {
9846                throw new SecurityException("Unable to find app for caller "
9847                        + caller
9848                        + " when revoking permission to uri " + uri);
9849            }
9850            if (uri == null) {
9851                Slog.w(TAG, "revokeUriPermission: null uri");
9852                return;
9853            }
9854
9855            if (!Intent.isAccessUriMode(modeFlags)) {
9856                return;
9857            }
9858
9859            final String authority = uri.getAuthority();
9860            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9861                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9862            if (pi == null) {
9863                Slog.w(TAG, "No content provider found for permission revoke: "
9864                        + uri.toSafeString());
9865                return;
9866            }
9867
9868            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9869                    modeFlags);
9870        }
9871    }
9872
9873    /**
9874     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9875     * given package.
9876     *
9877     * @param packageName Package name to match, or {@code null} to apply to all
9878     *            packages.
9879     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9880     *            to all users.
9881     * @param persistable If persistable grants should be removed.
9882     * @param targetOnly When {@code true}, only remove permissions where the app is the target,
9883     * not source.
9884     */
9885    @GuardedBy("this")
9886    private void removeUriPermissionsForPackageLocked(
9887            String packageName, int userHandle, boolean persistable, boolean targetOnly) {
9888        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9889            throw new IllegalArgumentException("Must narrow by either package or user");
9890        }
9891
9892        boolean persistChanged = false;
9893
9894        int N = mGrantedUriPermissions.size();
9895        for (int i = 0; i < N; i++) {
9896            final int targetUid = mGrantedUriPermissions.keyAt(i);
9897            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9898
9899            // Only inspect grants matching user
9900            if (userHandle == UserHandle.USER_ALL
9901                    || userHandle == UserHandle.getUserId(targetUid)) {
9902                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9903                    final UriPermission perm = it.next();
9904
9905                    // Only inspect grants matching package
9906                    if (packageName == null || (!targetOnly && perm.sourcePkg.equals(packageName))
9907                            || perm.targetPkg.equals(packageName)) {
9908                        // Hacky solution as part of fixing a security bug; ignore
9909                        // grants associated with DownloadManager so we don't have
9910                        // to immediately launch it to regrant the permissions
9911                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9912                                && !persistable) continue;
9913
9914                        persistChanged |= perm.revokeModes(persistable
9915                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9916
9917                        // Only remove when no modes remain; any persisted grants
9918                        // will keep this alive.
9919                        if (perm.modeFlags == 0) {
9920                            it.remove();
9921                        }
9922                    }
9923                }
9924
9925                if (perms.isEmpty()) {
9926                    mGrantedUriPermissions.remove(targetUid);
9927                    N--;
9928                    i--;
9929                }
9930            }
9931        }
9932
9933        if (persistChanged) {
9934            schedulePersistUriGrants();
9935        }
9936    }
9937
9938    @Override
9939    public IBinder newUriPermissionOwner(String name) {
9940        enforceNotIsolatedCaller("newUriPermissionOwner");
9941        synchronized(this) {
9942            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9943            return owner.getExternalTokenLocked();
9944        }
9945    }
9946
9947    @Override
9948    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9949        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9950        synchronized(this) {
9951            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9952            if (r == null) {
9953                throw new IllegalArgumentException("Activity does not exist; token="
9954                        + activityToken);
9955            }
9956            return r.getUriPermissionsLocked().getExternalTokenLocked();
9957        }
9958    }
9959    /**
9960     * @param uri This uri must NOT contain an embedded userId.
9961     * @param sourceUserId The userId in which the uri is to be resolved.
9962     * @param targetUserId The userId of the app that receives the grant.
9963     */
9964    @Override
9965    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9966            final int modeFlags, int sourceUserId, int targetUserId) {
9967        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9968                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9969                "grantUriPermissionFromOwner", null);
9970        synchronized(this) {
9971            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9972            if (owner == null) {
9973                throw new IllegalArgumentException("Unknown owner: " + token);
9974            }
9975            if (fromUid != Binder.getCallingUid()) {
9976                if (Binder.getCallingUid() != myUid()) {
9977                    // Only system code can grant URI permissions on behalf
9978                    // of other users.
9979                    throw new SecurityException("nice try");
9980                }
9981            }
9982            if (targetPkg == null) {
9983                throw new IllegalArgumentException("null target");
9984            }
9985            if (uri == null) {
9986                throw new IllegalArgumentException("null uri");
9987            }
9988
9989            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9990                    modeFlags, owner, targetUserId);
9991        }
9992    }
9993
9994    /**
9995     * @param uri This uri must NOT contain an embedded userId.
9996     * @param userId The userId in which the uri is to be resolved.
9997     */
9998    @Override
9999    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
10000        synchronized(this) {
10001            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
10002            if (owner == null) {
10003                throw new IllegalArgumentException("Unknown owner: " + token);
10004            }
10005
10006            if (uri == null) {
10007                owner.removeUriPermissionsLocked(mode);
10008            } else {
10009                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
10010                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
10011            }
10012        }
10013    }
10014
10015    private void schedulePersistUriGrants() {
10016        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
10017            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
10018                    10 * DateUtils.SECOND_IN_MILLIS);
10019        }
10020    }
10021
10022    private void writeGrantedUriPermissions() {
10023        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
10024
10025        final long startTime = SystemClock.uptimeMillis();
10026
10027        // Snapshot permissions so we can persist without lock
10028        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
10029        synchronized (this) {
10030            final int size = mGrantedUriPermissions.size();
10031            for (int i = 0; i < size; i++) {
10032                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10033                for (UriPermission perm : perms.values()) {
10034                    if (perm.persistedModeFlags != 0) {
10035                        persist.add(perm.snapshot());
10036                    }
10037                }
10038            }
10039        }
10040
10041        FileOutputStream fos = null;
10042        try {
10043            fos = mGrantFile.startWrite(startTime);
10044
10045            XmlSerializer out = new FastXmlSerializer();
10046            out.setOutput(fos, StandardCharsets.UTF_8.name());
10047            out.startDocument(null, true);
10048            out.startTag(null, TAG_URI_GRANTS);
10049            for (UriPermission.Snapshot perm : persist) {
10050                out.startTag(null, TAG_URI_GRANT);
10051                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
10052                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
10053                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
10054                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
10055                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
10056                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
10057                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
10058                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
10059                out.endTag(null, TAG_URI_GRANT);
10060            }
10061            out.endTag(null, TAG_URI_GRANTS);
10062            out.endDocument();
10063
10064            mGrantFile.finishWrite(fos);
10065        } catch (IOException e) {
10066            if (fos != null) {
10067                mGrantFile.failWrite(fos);
10068            }
10069        }
10070    }
10071
10072    @GuardedBy("this")
10073    private void readGrantedUriPermissionsLocked() {
10074        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
10075
10076        final long now = System.currentTimeMillis();
10077
10078        FileInputStream fis = null;
10079        try {
10080            fis = mGrantFile.openRead();
10081            final XmlPullParser in = Xml.newPullParser();
10082            in.setInput(fis, StandardCharsets.UTF_8.name());
10083
10084            int type;
10085            while ((type = in.next()) != END_DOCUMENT) {
10086                final String tag = in.getName();
10087                if (type == START_TAG) {
10088                    if (TAG_URI_GRANT.equals(tag)) {
10089                        final int sourceUserId;
10090                        final int targetUserId;
10091                        final int userHandle = readIntAttribute(in,
10092                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
10093                        if (userHandle != UserHandle.USER_NULL) {
10094                            // For backwards compatibility.
10095                            sourceUserId = userHandle;
10096                            targetUserId = userHandle;
10097                        } else {
10098                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
10099                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
10100                        }
10101                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
10102                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
10103                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
10104                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
10105                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
10106                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
10107
10108                        // Sanity check that provider still belongs to source package
10109                        // Both direct boot aware and unaware packages are fine as we
10110                        // will do filtering at query time to avoid multiple parsing.
10111                        final ProviderInfo pi = getProviderInfoLocked(
10112                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
10113                                        | MATCH_DIRECT_BOOT_UNAWARE);
10114                        if (pi != null && sourcePkg.equals(pi.packageName)) {
10115                            int targetUid = -1;
10116                            try {
10117                                targetUid = AppGlobals.getPackageManager().getPackageUid(
10118                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
10119                            } catch (RemoteException e) {
10120                            }
10121                            if (targetUid != -1) {
10122                                final UriPermission perm = findOrCreateUriPermissionLocked(
10123                                        sourcePkg, targetPkg, targetUid,
10124                                        new GrantUri(sourceUserId, uri, prefix));
10125                                perm.initPersistedModes(modeFlags, createdTime);
10126                            }
10127                        } else {
10128                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
10129                                    + " but instead found " + pi);
10130                        }
10131                    }
10132                }
10133            }
10134        } catch (FileNotFoundException e) {
10135            // Missing grants is okay
10136        } catch (IOException e) {
10137            Slog.wtf(TAG, "Failed reading Uri grants", e);
10138        } catch (XmlPullParserException e) {
10139            Slog.wtf(TAG, "Failed reading Uri grants", e);
10140        } finally {
10141            IoUtils.closeQuietly(fis);
10142        }
10143    }
10144
10145    /**
10146     * Updates (grants or revokes) a persitable URI permission.
10147     *
10148     * @param uri URI to be granted or revoked.
10149     * @param prefix if {@code false}, permission apply to this specific URI; if {@code true}, it
10150     * applies to all URIs that are prefixed by this URI.
10151     * @param packageName target package.
10152     * @param grant if {@code true} a new permission will be granted, otherwise an existing
10153     * permission will be revoked.
10154     * @param userId user handle
10155     *
10156     * @return whether or not the requested succeeded.
10157     *
10158     * @deprecated TODO(b/72055774): caller should use takePersistableUriPermission() or
10159     * releasePersistableUriPermission() instead, but such change will be made in a separate CL
10160     * so it can be easily reverted if it breaks existing functionality.
10161     */
10162    @Deprecated // STOPSHIP if not removed
10163    @Override
10164    public boolean updatePersistableUriPermission(Uri uri, boolean prefix, String packageName,
10165            boolean grant, int userId) {
10166        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10167                "updatePersistableUriPermission");
10168        final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId);
10169
10170        final GrantUri grantUri = new GrantUri(userId, uri, prefix);
10171
10172        boolean persistChanged = false;
10173        synchronized (this) {
10174            if (grant) { // Grant
10175                final String authority = uri.getAuthority();
10176                final ProviderInfo pi = getProviderInfoLocked(authority, userId, 0);
10177                if (pi == null) {
10178                    Slog.w(TAG, "No content provider found for authority " + authority);
10179                    return false;
10180                }
10181                final UriPermission permission = findOrCreateUriPermissionLocked(pi.packageName,
10182                        packageName, uid, grantUri);
10183                if (permission.isNew()) {
10184                    final int modeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
10185                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
10186                    permission.initPersistedModes(modeFlags, System.currentTimeMillis());
10187                    persistChanged = true;
10188                } else {
10189                    // Caller should not try to grant permission that is already granted.
10190                    Slog.w(TAG_URI_PERMISSION,
10191                            "permission already granted for " + grantUri.toSafeString());
10192                    return false;
10193                }
10194                persistChanged |= maybePrunePersistedUriGrantsLocked(uid);
10195            } else { // Revoke
10196                final UriPermission permission = findUriPermissionLocked(uid, grantUri);
10197                if (permission == null) {
10198                    // Caller should not try to revoke permission that is not granted.
10199                    Slog.v(TAG_URI_PERMISSION, "no permission for " + grantUri.toSafeString());
10200                    return false;
10201                } else {
10202                    permission.modeFlags = 0;
10203                    removeUriPermissionIfNeededLocked(permission);
10204                    persistChanged = true;
10205                }
10206            }
10207            if (persistChanged) {
10208                schedulePersistUriGrants();
10209            }
10210        }
10211        return true;
10212    }
10213
10214    /**
10215     * @param uri This uri must NOT contain an embedded userId.
10216     * @param userId The userId in which the uri is to be resolved.
10217     */
10218    @Override
10219    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
10220        enforceNotIsolatedCaller("takePersistableUriPermission");
10221
10222        Preconditions.checkFlagsArgument(modeFlags,
10223                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10224
10225        synchronized (this) {
10226            final int callingUid = Binder.getCallingUid();
10227            boolean persistChanged = false;
10228            GrantUri grantUri = new GrantUri(userId, uri, false);
10229
10230            UriPermission exactPerm = findUriPermissionLocked(callingUid, grantUri);
10231            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
10232                    new GrantUri(userId, uri, true));
10233
10234            final boolean exactValid = (exactPerm != null)
10235                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
10236            final boolean prefixValid = (prefixPerm != null)
10237                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
10238
10239            if (!(exactValid || prefixValid)) {
10240                throw new SecurityException("No persistable permission grants found for UID "
10241                        + callingUid + " and Uri " + grantUri.toSafeString());
10242            }
10243
10244            if (exactValid) {
10245                persistChanged |= exactPerm.takePersistableModes(modeFlags);
10246            }
10247            if (prefixValid) {
10248                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
10249            }
10250
10251            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
10252
10253            if (persistChanged) {
10254                schedulePersistUriGrants();
10255            }
10256        }
10257    }
10258
10259    /**
10260     * @param uri This uri must NOT contain an embedded userId.
10261     * @param userId The userId in which the uri is to be resolved.
10262     */
10263    @Override
10264    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
10265        enforceNotIsolatedCaller("releasePersistableUriPermission");
10266
10267        Preconditions.checkFlagsArgument(modeFlags,
10268                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
10269
10270        synchronized (this) {
10271            final int callingUid = Binder.getCallingUid();
10272            boolean persistChanged = false;
10273
10274            UriPermission exactPerm = findUriPermissionLocked(callingUid,
10275                    new GrantUri(userId, uri, false));
10276            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
10277                    new GrantUri(userId, uri, true));
10278            if (exactPerm == null && prefixPerm == null) {
10279                throw new SecurityException("No permission grants found for UID " + callingUid
10280                        + " and Uri " + uri.toSafeString());
10281            }
10282
10283            if (exactPerm != null) {
10284                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
10285                removeUriPermissionIfNeededLocked(exactPerm);
10286            }
10287            if (prefixPerm != null) {
10288                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
10289                removeUriPermissionIfNeededLocked(prefixPerm);
10290            }
10291
10292            if (persistChanged) {
10293                schedulePersistUriGrants();
10294            }
10295        }
10296    }
10297
10298    /**
10299     * Prune any older {@link UriPermission} for the given UID until outstanding
10300     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
10301     *
10302     * @return if any mutations occured that require persisting.
10303     */
10304    @GuardedBy("this")
10305    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
10306        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
10307        if (perms == null) return false;
10308        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
10309
10310        final ArrayList<UriPermission> persisted = Lists.newArrayList();
10311        for (UriPermission perm : perms.values()) {
10312            if (perm.persistedModeFlags != 0) {
10313                persisted.add(perm);
10314            }
10315        }
10316
10317        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
10318        if (trimCount <= 0) return false;
10319
10320        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
10321        for (int i = 0; i < trimCount; i++) {
10322            final UriPermission perm = persisted.get(i);
10323
10324            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
10325                    "Trimming grant created at " + perm.persistedCreateTime);
10326
10327            perm.releasePersistableModes(~0);
10328            removeUriPermissionIfNeededLocked(perm);
10329        }
10330
10331        return true;
10332    }
10333
10334    @Override
10335    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
10336            String packageName, boolean incoming) {
10337        enforceNotIsolatedCaller("getPersistedUriPermissions");
10338        Preconditions.checkNotNull(packageName, "packageName");
10339
10340        final int callingUid = Binder.getCallingUid();
10341        final int callingUserId = UserHandle.getUserId(callingUid);
10342        final IPackageManager pm = AppGlobals.getPackageManager();
10343        try {
10344            final int packageUid = pm.getPackageUid(packageName,
10345                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
10346            if (packageUid != callingUid) {
10347                throw new SecurityException(
10348                        "Package " + packageName + " does not belong to calling UID " + callingUid);
10349            }
10350        } catch (RemoteException e) {
10351            throw new SecurityException("Failed to verify package name ownership");
10352        }
10353
10354        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
10355        synchronized (this) {
10356            if (incoming) {
10357                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
10358                        callingUid);
10359                if (perms == null) {
10360                    Slog.w(TAG, "No permission grants found for " + packageName);
10361                } else {
10362                    for (int j = 0; j < perms.size(); j++) {
10363                        final UriPermission perm = perms.valueAt(j);
10364                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
10365                            result.add(perm.buildPersistedPublicApiObject());
10366                        }
10367                    }
10368                }
10369            } else {
10370                final int size = mGrantedUriPermissions.size();
10371                for (int i = 0; i < size; i++) {
10372                    final ArrayMap<GrantUri, UriPermission> perms =
10373                            mGrantedUriPermissions.valueAt(i);
10374                    for (int j = 0; j < perms.size(); j++) {
10375                        final UriPermission perm = perms.valueAt(j);
10376                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
10377                            result.add(perm.buildPersistedPublicApiObject());
10378                        }
10379                    }
10380                }
10381            }
10382        }
10383        return new ParceledListSlice<android.content.UriPermission>(result);
10384    }
10385
10386    @Override
10387    public ParceledListSlice<GrantedUriPermission> getGrantedUriPermissions(
10388            @Nullable String packageName, int userId) {
10389        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
10390                "getGrantedUriPermissions");
10391
10392        final List<GrantedUriPermission> result = new ArrayList<>();
10393        synchronized (this) {
10394            final int size = mGrantedUriPermissions.size();
10395            for (int i = 0; i < size; i++) {
10396                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
10397                for (int j = 0; j < perms.size(); j++) {
10398                    final UriPermission perm = perms.valueAt(j);
10399                    if ((packageName == null || packageName.equals(perm.targetPkg))
10400                            && perm.targetUserId == userId
10401                            && perm.persistedModeFlags != 0) {
10402                        result.add(perm.buildGrantedUriPermission());
10403                    }
10404                }
10405            }
10406        }
10407        return new ParceledListSlice<>(result);
10408    }
10409
10410    @Override
10411    public void clearGrantedUriPermissions(String packageName, int userId) {
10412        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
10413                "clearGrantedUriPermissions");
10414        synchronized(this) {
10415            removeUriPermissionsForPackageLocked(packageName, userId, true, true);
10416        }
10417    }
10418
10419    @Override
10420    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
10421        synchronized (this) {
10422            ProcessRecord app =
10423                who != null ? getRecordForAppLocked(who) : null;
10424            if (app == null) return;
10425
10426            Message msg = Message.obtain();
10427            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
10428            msg.obj = app;
10429            msg.arg1 = waiting ? 1 : 0;
10430            mUiHandler.sendMessage(msg);
10431        }
10432    }
10433
10434    @Override
10435    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
10436        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
10437        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
10438        outInfo.availMem = getFreeMemory();
10439        outInfo.totalMem = getTotalMemory();
10440        outInfo.threshold = homeAppMem;
10441        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
10442        outInfo.hiddenAppThreshold = cachedAppMem;
10443        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
10444                ProcessList.SERVICE_ADJ);
10445        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
10446                ProcessList.VISIBLE_APP_ADJ);
10447        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
10448                ProcessList.FOREGROUND_APP_ADJ);
10449    }
10450
10451    // =========================================================
10452    // TASK MANAGEMENT
10453    // =========================================================
10454
10455    @Override
10456    public List<IBinder> getAppTasks(String callingPackage) {
10457        int callingUid = Binder.getCallingUid();
10458        long ident = Binder.clearCallingIdentity();
10459        try {
10460            synchronized(this) {
10461                return mRecentTasks.getAppTasksList(callingUid, callingPackage);
10462            }
10463        } finally {
10464            Binder.restoreCallingIdentity(ident);
10465        }
10466    }
10467
10468    @Override
10469    public List<RunningTaskInfo> getTasks(int maxNum) {
10470       return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
10471    }
10472
10473    @Override
10474    public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType,
10475            @WindowingMode int ignoreWindowingMode) {
10476        final int callingUid = Binder.getCallingUid();
10477        ArrayList<RunningTaskInfo> list = new ArrayList<>();
10478
10479        synchronized(this) {
10480            if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
10481
10482            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
10483                    callingUid);
10484            mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
10485                    ignoreWindowingMode, callingUid, allowed);
10486        }
10487
10488        return list;
10489    }
10490
10491    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
10492        if (mRecentTasks.isCallerRecents(callingUid)) {
10493            // Always allow the recents component to get tasks
10494            return true;
10495        }
10496
10497        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
10498                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
10499        if (!allowed) {
10500            if (checkPermission(android.Manifest.permission.GET_TASKS,
10501                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
10502                // Temporary compatibility: some existing apps on the system image may
10503                // still be requesting the old permission and not switched to the new
10504                // one; if so, we'll still allow them full access.  This means we need
10505                // to see if they are holding the old permission and are a system app.
10506                try {
10507                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
10508                        allowed = true;
10509                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10510                                + " is using old GET_TASKS but privileged; allowing");
10511                    }
10512                } catch (RemoteException e) {
10513                }
10514            }
10515        }
10516        if (!allowed) {
10517            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
10518                    + " does not hold REAL_GET_TASKS; limiting output");
10519        }
10520        return allowed;
10521    }
10522
10523    @Override
10524    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
10525            int userId) {
10526        final int callingUid = Binder.getCallingUid();
10527        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
10528                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
10529        final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
10530                callingUid);
10531        final boolean detailed = checkCallingPermission(
10532                android.Manifest.permission.GET_DETAILED_TASKS)
10533                        == PackageManager.PERMISSION_GRANTED;
10534
10535        synchronized (this) {
10536            return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
10537                    callingUid);
10538        }
10539    }
10540
10541    @Override
10542    public ActivityManager.TaskDescription getTaskDescription(int id) {
10543        synchronized (this) {
10544            enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
10545            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10546                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10547            if (tr != null) {
10548                return tr.lastTaskDescription;
10549            }
10550        }
10551        return null;
10552    }
10553
10554    @Override
10555    public int addAppTask(IBinder activityToken, Intent intent,
10556            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10557        final int callingUid = Binder.getCallingUid();
10558        final long callingIdent = Binder.clearCallingIdentity();
10559
10560        try {
10561            synchronized (this) {
10562                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10563                if (r == null) {
10564                    throw new IllegalArgumentException("Activity does not exist; token="
10565                            + activityToken);
10566                }
10567                ComponentName comp = intent.getComponent();
10568                if (comp == null) {
10569                    throw new IllegalArgumentException("Intent " + intent
10570                            + " must specify explicit component");
10571                }
10572                if (thumbnail.getWidth() != mThumbnailWidth
10573                        || thumbnail.getHeight() != mThumbnailHeight) {
10574                    throw new IllegalArgumentException("Bad thumbnail size: got "
10575                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10576                            + mThumbnailWidth + "x" + mThumbnailHeight);
10577                }
10578                if (intent.getSelector() != null) {
10579                    intent.setSelector(null);
10580                }
10581                if (intent.getSourceBounds() != null) {
10582                    intent.setSourceBounds(null);
10583                }
10584                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10585                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10586                        // The caller has added this as an auto-remove task...  that makes no
10587                        // sense, so turn off auto-remove.
10588                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10589                    }
10590                }
10591                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10592                    mLastAddedTaskActivity = null;
10593                }
10594                ActivityInfo ainfo = mLastAddedTaskActivity;
10595                if (ainfo == null) {
10596                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10597                            comp, 0, UserHandle.getUserId(callingUid));
10598                    if (ainfo.applicationInfo.uid != callingUid) {
10599                        throw new SecurityException(
10600                                "Can't add task for another application: target uid="
10601                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10602                    }
10603                }
10604
10605                TaskRecord task = TaskRecord.create(this,
10606                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10607                        ainfo, intent, description);
10608                if (!mRecentTasks.addToBottom(task)) {
10609                    return INVALID_TASK_ID;
10610                }
10611                r.getStack().addTask(task, !ON_TOP, "addAppTask");
10612
10613                // TODO: Send the thumbnail to WM to store it.
10614
10615                return task.taskId;
10616            }
10617        } finally {
10618            Binder.restoreCallingIdentity(callingIdent);
10619        }
10620    }
10621
10622    @Override
10623    public Point getAppTaskThumbnailSize() {
10624        synchronized (this) {
10625            return new Point(mThumbnailWidth,  mThumbnailHeight);
10626        }
10627    }
10628
10629    @Override
10630    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10631        synchronized (this) {
10632            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10633            if (r != null) {
10634                r.setTaskDescription(td);
10635                final TaskRecord task = r.getTask();
10636                task.updateTaskDescription();
10637                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10638            }
10639        }
10640    }
10641
10642    @Override
10643    public void setTaskResizeable(int taskId, int resizeableMode) {
10644        synchronized (this) {
10645            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10646                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10647            if (task == null) {
10648                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10649                return;
10650            }
10651            task.setResizeMode(resizeableMode);
10652        }
10653    }
10654
10655    @Override
10656    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10657        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10658        long ident = Binder.clearCallingIdentity();
10659        try {
10660            synchronized (this) {
10661                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10662                if (task == null) {
10663                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10664                    return;
10665                }
10666                // Place the task in the right stack if it isn't there already based on
10667                // the requested bounds.
10668                // The stack transition logic is:
10669                // - a null bounds on a freeform task moves that task to fullscreen
10670                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10671                //   that task to freeform
10672                // - otherwise the task is not moved
10673                ActivityStack stack = task.getStack();
10674                if (!task.getWindowConfiguration().canResizeTask()) {
10675                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10676                }
10677                if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
10678                    stack = stack.getDisplay().getOrCreateStack(
10679                            WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
10680                } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
10681                    stack = stack.getDisplay().getOrCreateStack(
10682                            WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
10683                }
10684
10685                // Reparent the task to the right stack if necessary
10686                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10687                if (stack != task.getStack()) {
10688                    // Defer resume until the task is resized below
10689                    task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10690                            DEFER_RESUME, "resizeTask");
10691                    preserveWindow = false;
10692                }
10693
10694                // After reparenting (which only resizes the task to the stack bounds), resize the
10695                // task to the actual bounds provided
10696                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10697            }
10698        } finally {
10699            Binder.restoreCallingIdentity(ident);
10700        }
10701    }
10702
10703    @Override
10704    public Rect getTaskBounds(int taskId) {
10705        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10706        long ident = Binder.clearCallingIdentity();
10707        Rect rect = new Rect();
10708        try {
10709            synchronized (this) {
10710                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10711                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10712                if (task == null) {
10713                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10714                    return rect;
10715                }
10716                if (task.getStack() != null) {
10717                    // Return the bounds from window manager since it will be adjusted for various
10718                    // things like the presense of a docked stack for tasks that aren't resizeable.
10719                    task.getWindowContainerBounds(rect);
10720                } else {
10721                    // Task isn't in window manager yet since it isn't associated with a stack.
10722                    // Return the persist value from activity manager
10723                    if (!task.matchParentBounds()) {
10724                        rect.set(task.getBounds());
10725                    } else if (task.mLastNonFullscreenBounds != null) {
10726                        rect.set(task.mLastNonFullscreenBounds);
10727                    }
10728                }
10729            }
10730        } finally {
10731            Binder.restoreCallingIdentity(ident);
10732        }
10733        return rect;
10734    }
10735
10736    @Override
10737    public void cancelTaskWindowTransition(int taskId) {
10738        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10739                "cancelTaskWindowTransition()");
10740        final long ident = Binder.clearCallingIdentity();
10741        try {
10742            synchronized (this) {
10743                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10744                        MATCH_TASK_IN_STACKS_ONLY);
10745                if (task == null) {
10746                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10747                    return;
10748                }
10749                task.cancelWindowTransition();
10750            }
10751        } finally {
10752            Binder.restoreCallingIdentity(ident);
10753        }
10754    }
10755
10756    @Override
10757    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10758        enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10759        final long ident = Binder.clearCallingIdentity();
10760        try {
10761            final TaskRecord task;
10762            synchronized (this) {
10763                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10764                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
10765                if (task == null) {
10766                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10767                    return null;
10768                }
10769            }
10770            // Don't call this while holding the lock as this operation might hit the disk.
10771            return task.getSnapshot(reducedResolution);
10772        } finally {
10773            Binder.restoreCallingIdentity(ident);
10774        }
10775    }
10776
10777    @Override
10778    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10779        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10780                userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
10781
10782        final File passedIconFile = new File(filePath);
10783        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10784                passedIconFile.getName());
10785        if (!legitIconFile.getPath().equals(filePath)
10786                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10787            throw new IllegalArgumentException("Bad file path: " + filePath
10788                    + " passed for userId " + userId);
10789        }
10790        return mRecentTasks.getTaskDescriptionIcon(filePath);
10791    }
10792
10793    @Override
10794    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10795            throws RemoteException {
10796        final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
10797        final ActivityOptions activityOptions = safeOptions != null
10798                ? safeOptions.getOptions(mStackSupervisor)
10799                : null;
10800        if (activityOptions == null
10801                || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
10802                || activityOptions.getCustomInPlaceResId() == 0) {
10803            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10804                    "with valid animation");
10805        }
10806        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10807        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10808                activityOptions.getCustomInPlaceResId());
10809        mWindowManager.executeAppTransition();
10810    }
10811
10812    @Override
10813    public void removeStack(int stackId) {
10814        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
10815        synchronized (this) {
10816            final long ident = Binder.clearCallingIdentity();
10817            try {
10818                final ActivityStack stack = mStackSupervisor.getStack(stackId);
10819                if (stack == null) {
10820                    Slog.w(TAG, "removeStack: No stack with id=" + stackId);
10821                    return;
10822                }
10823                if (!stack.isActivityTypeStandardOrUndefined()) {
10824                    throw new IllegalArgumentException(
10825                            "Removing non-standard stack is not allowed.");
10826                }
10827                mStackSupervisor.removeStack(stack);
10828            } finally {
10829                Binder.restoreCallingIdentity(ident);
10830            }
10831        }
10832    }
10833
10834    /**
10835     * Removes stacks in the input windowing modes from the system if they are of activity type
10836     * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
10837     */
10838    @Override
10839    public void removeStacksInWindowingModes(int[] windowingModes) {
10840        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10841                "removeStacksInWindowingModes()");
10842        synchronized (this) {
10843            final long ident = Binder.clearCallingIdentity();
10844            try {
10845                mStackSupervisor.removeStacksInWindowingModes(windowingModes);
10846            } finally {
10847                Binder.restoreCallingIdentity(ident);
10848            }
10849        }
10850    }
10851
10852    @Override
10853    public void removeStacksWithActivityTypes(int[] activityTypes) {
10854        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
10855                "removeStacksWithActivityTypes()");
10856        synchronized (this) {
10857            final long ident = Binder.clearCallingIdentity();
10858            try {
10859                mStackSupervisor.removeStacksWithActivityTypes(activityTypes);
10860            } finally {
10861                Binder.restoreCallingIdentity(ident);
10862            }
10863        }
10864    }
10865
10866    @Override
10867    public void moveStackToDisplay(int stackId, int displayId) {
10868        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10869
10870        synchronized (this) {
10871            final long ident = Binder.clearCallingIdentity();
10872            try {
10873                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10874                        + " to displayId=" + displayId);
10875                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10876            } finally {
10877                Binder.restoreCallingIdentity(ident);
10878            }
10879        }
10880    }
10881
10882    @Override
10883    public boolean removeTask(int taskId) {
10884        enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
10885        synchronized (this) {
10886            final long ident = Binder.clearCallingIdentity();
10887            try {
10888                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
10889                        "remove-task");
10890            } finally {
10891                Binder.restoreCallingIdentity(ident);
10892            }
10893        }
10894    }
10895
10896    /**
10897     * TODO: Add mController hook
10898     */
10899    @Override
10900    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10901        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10902
10903        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10904        synchronized(this) {
10905            moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
10906                    false /* fromRecents */);
10907        }
10908    }
10909
10910    void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
10911            boolean fromRecents) {
10912
10913        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10914                Binder.getCallingUid(), -1, -1, "Task to front")) {
10915            SafeActivityOptions.abort(options);
10916            return;
10917        }
10918        final long origId = Binder.clearCallingIdentity();
10919        try {
10920            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10921            if (task == null) {
10922                Slog.d(TAG, "Could not find task for id: "+ taskId);
10923                return;
10924            }
10925            if (mLockTaskController.isLockTaskModeViolation(task)) {
10926                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10927                return;
10928            }
10929            ActivityOptions realOptions = options != null
10930                    ? options.getOptions(mStackSupervisor)
10931                    : null;
10932            mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
10933                    false /* forceNonResizable */);
10934
10935            final ActivityRecord topActivity = task.getTopActivity();
10936            if (topActivity != null) {
10937
10938                // We are reshowing a task, use a starting window to hide the initial draw delay
10939                // so the transition can start earlier.
10940                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10941                        true /* taskSwitch */, fromRecents);
10942            }
10943        } finally {
10944            Binder.restoreCallingIdentity(origId);
10945        }
10946        SafeActivityOptions.abort(options);
10947    }
10948
10949    /**
10950     * Attempts to move a task backwards in z-order (the order of activities within the task is
10951     * unchanged).
10952     *
10953     * There are several possible results of this call:
10954     * - if the task is locked, then we will show the lock toast
10955     * - if there is a task behind the provided task, then that task is made visible and resumed as
10956     *   this task is moved to the back
10957     * - otherwise, if there are no other tasks in the stack:
10958     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10959     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10960     *       (depending on whether it is visible)
10961     *     - otherwise, we simply return home and hide this task
10962     *
10963     * @param token A reference to the activity we wish to move
10964     * @param nonRoot If false then this only works if the activity is the root
10965     *                of a task; if true it will work for any activity in a task.
10966     * @return Returns true if the move completed, false if not.
10967     */
10968    @Override
10969    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10970        enforceNotIsolatedCaller("moveActivityTaskToBack");
10971        synchronized(this) {
10972            final long origId = Binder.clearCallingIdentity();
10973            try {
10974                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10975                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10976                if (task != null) {
10977                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10978                }
10979            } finally {
10980                Binder.restoreCallingIdentity(origId);
10981            }
10982        }
10983        return false;
10984    }
10985
10986    @Override
10987    public void moveTaskBackwards(int task) {
10988        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10989                "moveTaskBackwards()");
10990
10991        synchronized(this) {
10992            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10993                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10994                return;
10995            }
10996            final long origId = Binder.clearCallingIdentity();
10997            moveTaskBackwardsLocked(task);
10998            Binder.restoreCallingIdentity(origId);
10999        }
11000    }
11001
11002    private final void moveTaskBackwardsLocked(int task) {
11003        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
11004    }
11005
11006    @Override
11007    public int createStackOnDisplay(int displayId) throws RemoteException {
11008        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
11009        synchronized (this) {
11010            final ActivityDisplay display =
11011                    mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
11012            if (display == null) {
11013                return INVALID_STACK_ID;
11014            }
11015            // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
11016            final ActivityStack stack = display.createStack(
11017                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
11018                    ON_TOP);
11019            return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
11020        }
11021    }
11022
11023    @Override
11024    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
11025        synchronized (this) {
11026            final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
11027            if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
11028                return stack.mDisplayId;
11029            }
11030            return DEFAULT_DISPLAY;
11031        }
11032    }
11033
11034    @Override
11035    public void exitFreeformMode(IBinder token) throws RemoteException {
11036        synchronized (this) {
11037            long ident = Binder.clearCallingIdentity();
11038            try {
11039                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11040                if (r == null) {
11041                    throw new IllegalArgumentException(
11042                            "exitFreeformMode: No activity record matching token=" + token);
11043                }
11044
11045                final ActivityStack stack = r.getStack();
11046                if (stack == null || !stack.inFreeformWindowingMode()) {
11047                    throw new IllegalStateException(
11048                            "exitFreeformMode: You can only go fullscreen from freeform.");
11049                }
11050
11051                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11052            } finally {
11053                Binder.restoreCallingIdentity(ident);
11054            }
11055        }
11056    }
11057
11058    @Override
11059    public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
11060        if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
11061            setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
11062                    toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
11063            return;
11064        }
11065        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
11066        synchronized (this) {
11067            final long ident = Binder.clearCallingIdentity();
11068            try {
11069                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11070                if (task == null) {
11071                    Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
11072                    return;
11073                }
11074
11075                if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
11076                        + " to windowingMode=" + windowingMode + " toTop=" + toTop);
11077
11078                if (!task.isActivityTypeStandardOrUndefined()) {
11079                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11080                            + " non-standard task " + taskId + " to windowing mode="
11081                            + windowingMode);
11082                }
11083
11084                final ActivityStack stack = task.getStack();
11085                if (toTop) {
11086                    stack.moveToFront("setTaskWindowingMode", task);
11087                }
11088                stack.setWindowingMode(windowingMode);
11089            } finally {
11090                Binder.restoreCallingIdentity(ident);
11091            }
11092        }
11093    }
11094
11095    /**
11096     * Moves the specified task to the primary-split-screen stack.
11097     *
11098     * @param taskId Id of task to move.
11099     * @param createMode The mode the primary split screen stack should be created in if it doesn't
11100     *                   exist already. See
11101     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT}
11102     *                   and
11103     *                   {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT}
11104     * @param toTop If the task and stack should be moved to the top.
11105     * @param animate Whether we should play an animation for the moving the task.
11106     * @param initialBounds If the primary stack gets created, it will use these bounds for the
11107     *                      stack. Pass {@code null} to use default bounds.
11108     * @param showRecents If the recents activity should be shown on the other side of the task
11109     *                    going into split-screen mode.
11110     */
11111    @Override
11112    public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop,
11113            boolean animate, Rect initialBounds, boolean showRecents) {
11114        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11115                "setTaskWindowingModeSplitScreenPrimary()");
11116        synchronized (this) {
11117            long ident = Binder.clearCallingIdentity();
11118            try {
11119                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11120                if (task == null) {
11121                    Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId);
11122                    return false;
11123                }
11124                if (DEBUG_STACK) Slog.d(TAG_STACK,
11125                        "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId
11126                        + " to createMode=" + createMode + " toTop=" + toTop);
11127                if (!task.isActivityTypeStandardOrUndefined()) {
11128                    throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move"
11129                            + " non-standard task " + taskId + " to split-screen windowing mode");
11130                }
11131
11132                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
11133                final int windowingMode = task.getWindowingMode();
11134                final ActivityStack stack = task.getStack();
11135                if (toTop) {
11136                    stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task);
11137                }
11138                stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents,
11139                        false /* enteringSplitScreenMode */);
11140                return windowingMode != task.getWindowingMode();
11141            } finally {
11142                Binder.restoreCallingIdentity(ident);
11143            }
11144        }
11145    }
11146
11147    @Override
11148    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
11149        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
11150        synchronized (this) {
11151            long ident = Binder.clearCallingIdentity();
11152            try {
11153                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11154                if (task == null) {
11155                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
11156                    return;
11157                }
11158
11159                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
11160                        + " to stackId=" + stackId + " toTop=" + toTop);
11161
11162                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11163                if (stack == null) {
11164                    throw new IllegalStateException(
11165                            "moveTaskToStack: No stack for stackId=" + stackId);
11166                }
11167                if (!stack.isActivityTypeStandardOrUndefined()) {
11168                    throw new IllegalArgumentException("moveTaskToStack: Attempt to move task "
11169                            + taskId + " to stack " + stackId);
11170                }
11171                if (stack.inSplitScreenPrimaryWindowingMode()) {
11172                    mWindowManager.setDockedStackCreateState(
11173                            SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
11174                }
11175                task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
11176                        "moveTaskToStack");
11177            } finally {
11178                Binder.restoreCallingIdentity(ident);
11179            }
11180        }
11181    }
11182
11183    /**
11184     * Dismisses split-screen multi-window mode.
11185     * @param toTop If true the current primary split-screen stack will be placed or left on top.
11186     */
11187    @Override
11188    public void dismissSplitScreenMode(boolean toTop) {
11189        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
11190        final long ident = Binder.clearCallingIdentity();
11191        try {
11192            synchronized (this) {
11193                final ActivityStack stack =
11194                        mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
11195                if (stack == null) {
11196                    Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
11197                    return;
11198                }
11199
11200                if (toTop) {
11201                    // Caller wants the current split-screen primary stack to be the top stack after
11202                    // it goes fullscreen, so move it to the front.
11203                    stack.moveToFront("dismissSplitScreenMode");
11204                } else if (mStackSupervisor.isFocusedStack(stack)) {
11205                    // In this case the current split-screen primary stack shouldn't be the top
11206                    // stack after it goes fullscreen, but it current has focus, so we move the
11207                    // focus to the top-most split-screen secondary stack next to it.
11208                    final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
11209                            WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
11210                    if (otherStack != null) {
11211                        otherStack.moveToFront("dismissSplitScreenMode_other");
11212                    }
11213                }
11214
11215                stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
11216            }
11217        } finally {
11218            Binder.restoreCallingIdentity(ident);
11219        }
11220    }
11221
11222    /**
11223     * Dismisses Pip
11224     * @param animate True if the dismissal should be animated.
11225     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
11226     *                          default animation duration should be used.
11227     */
11228    @Override
11229    public void dismissPip(boolean animate, int animationDuration) {
11230        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
11231        final long ident = Binder.clearCallingIdentity();
11232        try {
11233            synchronized (this) {
11234                final PinnedActivityStack stack =
11235                        mStackSupervisor.getDefaultDisplay().getPinnedStack();
11236                if (stack == null) {
11237                    Slog.w(TAG, "dismissPip: pinned stack not found.");
11238                    return;
11239                }
11240                if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11241                    throw new IllegalArgumentException("Stack: " + stack
11242                            + " doesn't support animated resize.");
11243                }
11244                if (animate) {
11245                    stack.animateResizePinnedStack(null /* sourceHintBounds */,
11246                            null /* destBounds */, animationDuration, false /* fromFullscreen */);
11247                } else {
11248                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
11249                }
11250            }
11251        } finally {
11252            Binder.restoreCallingIdentity(ident);
11253        }
11254    }
11255
11256    /**
11257     * Moves the top activity in the input stackId to the pinned stack.
11258     *
11259     * @param stackId Id of stack to move the top activity to pinned stack.
11260     * @param bounds Bounds to use for pinned stack.
11261     *
11262     * @return True if the top activity of the input stack was successfully moved to the pinned
11263     *          stack.
11264     */
11265    @Override
11266    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
11267        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
11268                "moveTopActivityToPinnedStack()");
11269        synchronized (this) {
11270            if (!mSupportsPictureInPicture) {
11271                throw new IllegalStateException("moveTopActivityToPinnedStack:"
11272                        + "Device doesn't support picture-in-picture mode");
11273            }
11274
11275            long ident = Binder.clearCallingIdentity();
11276            try {
11277                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
11278            } finally {
11279                Binder.restoreCallingIdentity(ident);
11280            }
11281        }
11282    }
11283
11284    @Override
11285    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
11286            boolean preserveWindows, boolean animate, int animationDuration) {
11287        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
11288        long ident = Binder.clearCallingIdentity();
11289        try {
11290            synchronized (this) {
11291                if (animate) {
11292                    final PinnedActivityStack stack = mStackSupervisor.getStack(stackId);
11293                    if (stack == null) {
11294                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11295                        return;
11296                    }
11297                    if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
11298                        throw new IllegalArgumentException("Stack: " + stackId
11299                                + " doesn't support animated resize.");
11300                    }
11301                    stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds,
11302                            animationDuration, false /* fromFullscreen */);
11303                } else {
11304                    final ActivityStack stack = mStackSupervisor.getStack(stackId);
11305                    if (stack == null) {
11306                        Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
11307                        return;
11308                    }
11309                    mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */,
11310                            null /* tempTaskInsetBounds */, preserveWindows,
11311                            allowResizeInDockedMode, !DEFER_RESUME);
11312                }
11313            }
11314        } finally {
11315            Binder.restoreCallingIdentity(ident);
11316        }
11317    }
11318
11319    @Override
11320    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
11321            Rect tempDockedTaskInsetBounds,
11322            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
11323        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
11324        long ident = Binder.clearCallingIdentity();
11325        try {
11326            synchronized (this) {
11327                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
11328                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
11329                        PRESERVE_WINDOWS);
11330            }
11331        } finally {
11332            Binder.restoreCallingIdentity(ident);
11333        }
11334    }
11335
11336    @Override
11337    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
11338        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
11339        final long ident = Binder.clearCallingIdentity();
11340        try {
11341            synchronized (this) {
11342                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
11343            }
11344        } finally {
11345            Binder.restoreCallingIdentity(ident);
11346        }
11347    }
11348
11349    /**
11350     * Try to place task to provided position. The final position might be different depending on
11351     * current user and stacks state. The task will be moved to target stack if it's currently in
11352     * different stack.
11353     */
11354    @Override
11355    public void positionTaskInStack(int taskId, int stackId, int position) {
11356        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
11357        synchronized (this) {
11358            long ident = Binder.clearCallingIdentity();
11359            try {
11360                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
11361                        + taskId + " in stackId=" + stackId + " at position=" + position);
11362                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11363                if (task == null) {
11364                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
11365                            + taskId);
11366                }
11367
11368                final ActivityStack stack = mStackSupervisor.getStack(stackId);
11369
11370                if (stack == null) {
11371                    throw new IllegalArgumentException("positionTaskInStack: no stack for id="
11372                            + stackId);
11373                }
11374                if (!stack.isActivityTypeStandardOrUndefined()) {
11375                    throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
11376                            + " the position of task " + taskId + " in/to non-standard stack");
11377                }
11378
11379                // TODO: Have the callers of this API call a separate reparent method if that is
11380                // what they intended to do vs. having this method also do reparenting.
11381                if (task.getStack() == stack) {
11382                    // Change position in current stack.
11383                    stack.positionChildAt(task, position);
11384                } else {
11385                    // Reparent to new stack.
11386                    task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
11387                            !DEFER_RESUME, "positionTaskInStack");
11388                }
11389            } finally {
11390                Binder.restoreCallingIdentity(ident);
11391            }
11392        }
11393    }
11394
11395    @Override
11396    public List<StackInfo> getAllStackInfos() {
11397        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
11398        long ident = Binder.clearCallingIdentity();
11399        try {
11400            synchronized (this) {
11401                return mStackSupervisor.getAllStackInfosLocked();
11402            }
11403        } finally {
11404            Binder.restoreCallingIdentity(ident);
11405        }
11406    }
11407
11408    @Override
11409    public StackInfo getStackInfo(int windowingMode, int activityType) {
11410        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
11411        long ident = Binder.clearCallingIdentity();
11412        try {
11413            synchronized (this) {
11414                return mStackSupervisor.getStackInfo(windowingMode, activityType);
11415            }
11416        } finally {
11417            Binder.restoreCallingIdentity(ident);
11418        }
11419    }
11420
11421    @Override
11422    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
11423        synchronized(this) {
11424            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
11425        }
11426    }
11427
11428    @Override
11429    public void updateDeviceOwner(String packageName) {
11430        final int callingUid = Binder.getCallingUid();
11431        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11432            throw new SecurityException("updateDeviceOwner called from non-system process");
11433        }
11434        synchronized (this) {
11435            mDeviceOwnerName = packageName;
11436        }
11437    }
11438
11439    @Override
11440    public void updateLockTaskPackages(int userId, String[] packages) {
11441        final int callingUid = Binder.getCallingUid();
11442        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11443            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11444                    "updateLockTaskPackages()");
11445        }
11446        synchronized (this) {
11447            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
11448                    Arrays.toString(packages));
11449            mLockTaskController.updateLockTaskPackages(userId, packages);
11450        }
11451    }
11452
11453    @Override
11454    public void updateLockTaskFeatures(int userId, int flags) {
11455        final int callingUid = Binder.getCallingUid();
11456        if (callingUid != 0 && callingUid != SYSTEM_UID) {
11457            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
11458                    "updateLockTaskFeatures()");
11459        }
11460        synchronized (this) {
11461            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
11462                    Integer.toHexString(flags));
11463            mLockTaskController.updateLockTaskFeatures(userId, flags);
11464        }
11465    }
11466
11467    private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
11468        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
11469        if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
11470            return;
11471        }
11472
11473        final ActivityStack stack = mStackSupervisor.getFocusedStack();
11474        if (stack == null || task != stack.topTask()) {
11475            throw new IllegalArgumentException("Invalid task, not in foreground");
11476        }
11477
11478        // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
11479        // system or a specific app.
11480        // * System-initiated requests will only start the pinned mode (screen pinning)
11481        // * App-initiated requests
11482        //   - will put the device in fully locked mode (LockTask), if the app is whitelisted
11483        //   - will start the pinned mode, otherwise
11484        final int callingUid = Binder.getCallingUid();
11485        long ident = Binder.clearCallingIdentity();
11486        try {
11487            // When a task is locked, dismiss the pinned stack if it exists
11488            mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
11489
11490            mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
11491        } finally {
11492            Binder.restoreCallingIdentity(ident);
11493        }
11494    }
11495
11496    @Override
11497    public void startLockTaskModeByToken(IBinder token) {
11498        synchronized (this) {
11499            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11500            if (r == null) {
11501                return;
11502            }
11503            startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
11504        }
11505    }
11506
11507    @Override
11508    public void startSystemLockTaskMode(int taskId) throws RemoteException {
11509        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11510        // This makes inner call to look as if it was initiated by system.
11511        long ident = Binder.clearCallingIdentity();
11512        try {
11513            synchronized (this) {
11514                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11515
11516                // When starting lock task mode the stack must be in front and focused
11517                task.getStack().moveToFront("startSystemLockTaskMode");
11518                startLockTaskModeLocked(task, true /* isSystemCaller */);
11519            }
11520        } finally {
11521            Binder.restoreCallingIdentity(ident);
11522        }
11523    }
11524
11525    @Override
11526    public void stopLockTaskModeByToken(IBinder token) {
11527        synchronized (this) {
11528            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11529            if (r == null) {
11530                return;
11531            }
11532            stopLockTaskModeInternal(r.getTask(), false /* isSystemCaller */);
11533        }
11534    }
11535
11536    /**
11537     * This API should be called by SystemUI only when user perform certain action to dismiss
11538     * lock task mode. We should only dismiss pinned lock task mode in this case.
11539     */
11540    @Override
11541    public void stopSystemLockTaskMode() throws RemoteException {
11542        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
11543        stopLockTaskModeInternal(null, true /* isSystemCaller */);
11544    }
11545
11546    private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
11547        final int callingUid = Binder.getCallingUid();
11548        long ident = Binder.clearCallingIdentity();
11549        try {
11550            synchronized (this) {
11551                mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
11552            }
11553            // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
11554            // task and jumping straight into a call in the case of emergency call back.
11555            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11556            if (tm != null) {
11557                tm.showInCallScreen(false);
11558            }
11559        } finally {
11560            Binder.restoreCallingIdentity(ident);
11561        }
11562    }
11563
11564    @Override
11565    public boolean isInLockTaskMode() {
11566        return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
11567    }
11568
11569    @Override
11570    public int getLockTaskModeState() {
11571        synchronized (this) {
11572            return mLockTaskController.getLockTaskModeState();
11573        }
11574    }
11575
11576    @Override
11577    public void showLockTaskEscapeMessage(IBinder token) {
11578        synchronized (this) {
11579            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11580            if (r == null) {
11581                return;
11582            }
11583            mLockTaskController.showLockTaskToast();
11584        }
11585    }
11586
11587    @Override
11588    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11589            throws RemoteException {
11590        synchronized (this) {
11591            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11592            if (r == null) {
11593                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11594                        + token);
11595                return;
11596            }
11597            final long origId = Binder.clearCallingIdentity();
11598            try {
11599                r.setDisablePreviewScreenshots(disable);
11600            } finally {
11601                Binder.restoreCallingIdentity(origId);
11602            }
11603        }
11604    }
11605
11606    // =========================================================
11607    // CONTENT PROVIDERS
11608    // =========================================================
11609
11610    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11611        List<ProviderInfo> providers = null;
11612        try {
11613            providers = AppGlobals.getPackageManager()
11614                    .queryContentProviders(app.processName, app.uid,
11615                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11616                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11617                    .getList();
11618        } catch (RemoteException ex) {
11619        }
11620        if (DEBUG_MU) Slog.v(TAG_MU,
11621                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11622        int userId = app.userId;
11623        if (providers != null) {
11624            int N = providers.size();
11625            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11626            for (int i=0; i<N; i++) {
11627                // TODO: keep logic in sync with installEncryptionUnawareProviders
11628                ProviderInfo cpi =
11629                    (ProviderInfo)providers.get(i);
11630                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11631                        cpi.name, cpi.flags);
11632                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11633                    // This is a singleton provider, but a user besides the
11634                    // default user is asking to initialize a process it runs
11635                    // in...  well, no, it doesn't actually run in this process,
11636                    // it runs in the process of the default user.  Get rid of it.
11637                    providers.remove(i);
11638                    N--;
11639                    i--;
11640                    continue;
11641                }
11642
11643                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11644                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11645                if (cpr == null) {
11646                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11647                    mProviderMap.putProviderByClass(comp, cpr);
11648                }
11649                if (DEBUG_MU) Slog.v(TAG_MU,
11650                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11651                app.pubProviders.put(cpi.name, cpr);
11652                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11653                    // Don't add this if it is a platform component that is marked
11654                    // to run in multiple processes, because this is actually
11655                    // part of the framework so doesn't make sense to track as a
11656                    // separate apk in the process.
11657                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11658                            mProcessStats);
11659                }
11660                notifyPackageUse(cpi.applicationInfo.packageName,
11661                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11662            }
11663        }
11664        return providers;
11665    }
11666
11667    /**
11668     * Check if the calling UID has a possible chance at accessing the provider
11669     * at the given authority and user.
11670     */
11671    public String checkContentProviderAccess(String authority, int userId) {
11672        if (userId == UserHandle.USER_ALL) {
11673            mContext.enforceCallingOrSelfPermission(
11674                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11675            userId = UserHandle.getCallingUserId();
11676        }
11677
11678        ProviderInfo cpi = null;
11679        try {
11680            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11681                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11682                            | PackageManager.MATCH_DISABLED_COMPONENTS
11683                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11684                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11685                    userId);
11686        } catch (RemoteException ignored) {
11687        }
11688        if (cpi == null) {
11689            return "Failed to find provider " + authority + " for user " + userId
11690                    + "; expected to find a valid ContentProvider for this authority";
11691        }
11692
11693        ProcessRecord r = null;
11694        synchronized (mPidsSelfLocked) {
11695            r = mPidsSelfLocked.get(Binder.getCallingPid());
11696        }
11697        if (r == null) {
11698            return "Failed to find PID " + Binder.getCallingPid();
11699        }
11700
11701        synchronized (this) {
11702            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11703        }
11704    }
11705
11706    /**
11707     * Check if {@link ProcessRecord} has a possible chance at accessing the
11708     * given {@link ProviderInfo}. Final permission checking is always done
11709     * in {@link ContentProvider}.
11710     */
11711    private final String checkContentProviderPermissionLocked(
11712            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11713        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11714        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11715        boolean checkedGrants = false;
11716        if (checkUser) {
11717            // Looking for cross-user grants before enforcing the typical cross-users permissions
11718            int tmpTargetUserId = mUserController.unsafeConvertIncomingUser(userId);
11719            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11720                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11721                    return null;
11722                }
11723                checkedGrants = true;
11724            }
11725            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11726                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11727            if (userId != tmpTargetUserId) {
11728                // When we actually went to determine the final targer user ID, this ended
11729                // up different than our initial check for the authority.  This is because
11730                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11731                // SELF.  So we need to re-check the grants again.
11732                checkedGrants = false;
11733            }
11734        }
11735        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11736                cpi.applicationInfo.uid, cpi.exported)
11737                == PackageManager.PERMISSION_GRANTED) {
11738            return null;
11739        }
11740        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11741                cpi.applicationInfo.uid, cpi.exported)
11742                == PackageManager.PERMISSION_GRANTED) {
11743            return null;
11744        }
11745
11746        PathPermission[] pps = cpi.pathPermissions;
11747        if (pps != null) {
11748            int i = pps.length;
11749            while (i > 0) {
11750                i--;
11751                PathPermission pp = pps[i];
11752                String pprperm = pp.getReadPermission();
11753                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11754                        cpi.applicationInfo.uid, cpi.exported)
11755                        == PackageManager.PERMISSION_GRANTED) {
11756                    return null;
11757                }
11758                String ppwperm = pp.getWritePermission();
11759                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11760                        cpi.applicationInfo.uid, cpi.exported)
11761                        == PackageManager.PERMISSION_GRANTED) {
11762                    return null;
11763                }
11764            }
11765        }
11766        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11767            return null;
11768        }
11769
11770        final String suffix;
11771        if (!cpi.exported) {
11772            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11773        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11774            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11775        } else {
11776            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11777        }
11778        final String msg = "Permission Denial: opening provider " + cpi.name
11779                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11780                + ", uid=" + callingUid + ")" + suffix;
11781        Slog.w(TAG, msg);
11782        return msg;
11783    }
11784
11785    /**
11786     * Returns if the ContentProvider has granted a uri to callingUid
11787     */
11788    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11789        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11790        if (perms != null) {
11791            for (int i=perms.size()-1; i>=0; i--) {
11792                GrantUri grantUri = perms.keyAt(i);
11793                if (grantUri.sourceUserId == userId || !checkUser) {
11794                    if (matchesProvider(grantUri.uri, cpi)) {
11795                        return true;
11796                    }
11797                }
11798            }
11799        }
11800        return false;
11801    }
11802
11803    /**
11804     * Returns true if the uri authority is one of the authorities specified in the provider.
11805     */
11806    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11807        String uriAuth = uri.getAuthority();
11808        String cpiAuth = cpi.authority;
11809        if (cpiAuth.indexOf(';') == -1) {
11810            return cpiAuth.equals(uriAuth);
11811        }
11812        String[] cpiAuths = cpiAuth.split(";");
11813        int length = cpiAuths.length;
11814        for (int i = 0; i < length; i++) {
11815            if (cpiAuths[i].equals(uriAuth)) return true;
11816        }
11817        return false;
11818    }
11819
11820    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11821            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11822        if (r != null) {
11823            for (int i=0; i<r.conProviders.size(); i++) {
11824                ContentProviderConnection conn = r.conProviders.get(i);
11825                if (conn.provider == cpr) {
11826                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11827                            "Adding provider requested by "
11828                            + r.processName + " from process "
11829                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11830                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11831                    if (stable) {
11832                        conn.stableCount++;
11833                        conn.numStableIncs++;
11834                    } else {
11835                        conn.unstableCount++;
11836                        conn.numUnstableIncs++;
11837                    }
11838                    return conn;
11839                }
11840            }
11841            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11842            if (stable) {
11843                conn.stableCount = 1;
11844                conn.numStableIncs = 1;
11845            } else {
11846                conn.unstableCount = 1;
11847                conn.numUnstableIncs = 1;
11848            }
11849            cpr.connections.add(conn);
11850            r.conProviders.add(conn);
11851            startAssociationLocked(r.uid, r.processName, r.curProcState,
11852                    cpr.uid, cpr.name, cpr.info.processName);
11853            return conn;
11854        }
11855        cpr.addExternalProcessHandleLocked(externalProcessToken);
11856        return null;
11857    }
11858
11859    boolean decProviderCountLocked(ContentProviderConnection conn,
11860            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11861        if (conn != null) {
11862            cpr = conn.provider;
11863            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11864                    "Removing provider requested by "
11865                    + conn.client.processName + " from process "
11866                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11867                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11868            if (stable) {
11869                conn.stableCount--;
11870            } else {
11871                conn.unstableCount--;
11872            }
11873            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11874                cpr.connections.remove(conn);
11875                conn.client.conProviders.remove(conn);
11876                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11877                    // The client is more important than last activity -- note the time this
11878                    // is happening, so we keep the old provider process around a bit as last
11879                    // activity to avoid thrashing it.
11880                    if (cpr.proc != null) {
11881                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11882                    }
11883                }
11884                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11885                return true;
11886            }
11887            return false;
11888        }
11889        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11890        return false;
11891    }
11892
11893    private void checkTime(long startTime, String where) {
11894        long now = SystemClock.uptimeMillis();
11895        if ((now-startTime) > 50) {
11896            // If we are taking more than 50ms, log about it.
11897            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11898        }
11899    }
11900
11901    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11902            PROC_SPACE_TERM,
11903            PROC_SPACE_TERM|PROC_PARENS,
11904            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11905    };
11906
11907    private final long[] mProcessStateStatsLongs = new long[1];
11908
11909    private boolean isProcessAliveLocked(ProcessRecord proc) {
11910        if (proc.pid <= 0) {
11911            if (DEBUG_OOM_ADJ) Slog.d(TAG, "Process hasn't started yet: " + proc);
11912            return false;
11913        }
11914        if (proc.procStatFile == null) {
11915            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11916        }
11917        mProcessStateStatsLongs[0] = 0;
11918        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11919                mProcessStateStatsLongs, null)) {
11920            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11921            return false;
11922        }
11923        final long state = mProcessStateStatsLongs[0];
11924        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11925                + (char)state);
11926        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11927    }
11928
11929    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11930            String name, IBinder token, boolean stable, int userId) {
11931        ContentProviderRecord cpr;
11932        ContentProviderConnection conn = null;
11933        ProviderInfo cpi = null;
11934
11935        synchronized(this) {
11936            long startTime = SystemClock.uptimeMillis();
11937
11938            ProcessRecord r = null;
11939            if (caller != null) {
11940                r = getRecordForAppLocked(caller);
11941                if (r == null) {
11942                    throw new SecurityException(
11943                            "Unable to find app for caller " + caller
11944                          + " (pid=" + Binder.getCallingPid()
11945                          + ") when getting content provider " + name);
11946                }
11947            }
11948
11949            boolean checkCrossUser = true;
11950
11951            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11952
11953            // First check if this content provider has been published...
11954            cpr = mProviderMap.getProviderByName(name, userId);
11955            // If that didn't work, check if it exists for user 0 and then
11956            // verify that it's a singleton provider before using it.
11957            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11958                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11959                if (cpr != null) {
11960                    cpi = cpr.info;
11961                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11962                            cpi.name, cpi.flags)
11963                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11964                        userId = UserHandle.USER_SYSTEM;
11965                        checkCrossUser = false;
11966                    } else {
11967                        cpr = null;
11968                        cpi = null;
11969                    }
11970                }
11971            }
11972
11973            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11974            if (providerRunning) {
11975                cpi = cpr.info;
11976                String msg;
11977                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11978                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11979                        != null) {
11980                    throw new SecurityException(msg);
11981                }
11982                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11983
11984                if (r != null && cpr.canRunHere(r)) {
11985                    // This provider has been published or is in the process
11986                    // of being published...  but it is also allowed to run
11987                    // in the caller's process, so don't make a connection
11988                    // and just let the caller instantiate its own instance.
11989                    ContentProviderHolder holder = cpr.newHolder(null);
11990                    // don't give caller the provider object, it needs
11991                    // to make its own.
11992                    holder.provider = null;
11993                    return holder;
11994                }
11995                // Don't expose providers between normal apps and instant apps
11996                try {
11997                    if (AppGlobals.getPackageManager()
11998                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11999                        return null;
12000                    }
12001                } catch (RemoteException e) {
12002                }
12003
12004                final long origId = Binder.clearCallingIdentity();
12005
12006                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
12007
12008                // In this case the provider instance already exists, so we can
12009                // return it right away.
12010                conn = incProviderCountLocked(r, cpr, token, stable);
12011                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
12012                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12013                        // If this is a perceptible app accessing the provider,
12014                        // make sure to count it as being accessed and thus
12015                        // back up on the LRU list.  This is good because
12016                        // content providers are often expensive to start.
12017                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
12018                        updateLruProcessLocked(cpr.proc, false, null);
12019                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
12020                    }
12021                }
12022
12023                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
12024                final int verifiedAdj = cpr.proc.verifiedAdj;
12025                boolean success = updateOomAdjLocked(cpr.proc, true);
12026                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
12027                // if the process has been successfully adjusted.  So to reduce races with
12028                // it, we will check whether the process still exists.  Note that this doesn't
12029                // completely get rid of races with LMK killing the process, but should make
12030                // them much smaller.
12031                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
12032                    success = false;
12033                }
12034                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
12035                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
12036                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
12037                // NOTE: there is still a race here where a signal could be
12038                // pending on the process even though we managed to update its
12039                // adj level.  Not sure what to do about this, but at least
12040                // the race is now smaller.
12041                if (!success) {
12042                    // Uh oh...  it looks like the provider's process
12043                    // has been killed on us.  We need to wait for a new
12044                    // process to be started, and make sure its death
12045                    // doesn't kill our process.
12046                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
12047                            + " is crashing; detaching " + r);
12048                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
12049                    checkTime(startTime, "getContentProviderImpl: before appDied");
12050                    appDiedLocked(cpr.proc);
12051                    checkTime(startTime, "getContentProviderImpl: after appDied");
12052                    if (!lastRef) {
12053                        // This wasn't the last ref our process had on
12054                        // the provider...  we have now been killed, bail.
12055                        return null;
12056                    }
12057                    providerRunning = false;
12058                    conn = null;
12059                } else {
12060                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
12061                }
12062
12063                Binder.restoreCallingIdentity(origId);
12064            }
12065
12066            if (!providerRunning) {
12067                try {
12068                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
12069                    cpi = AppGlobals.getPackageManager().
12070                        resolveContentProvider(name,
12071                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
12072                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
12073                } catch (RemoteException ex) {
12074                }
12075                if (cpi == null) {
12076                    return null;
12077                }
12078                // If the provider is a singleton AND
12079                // (it's a call within the same user || the provider is a
12080                // privileged app)
12081                // Then allow connecting to the singleton provider
12082                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
12083                        cpi.name, cpi.flags)
12084                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
12085                if (singleton) {
12086                    userId = UserHandle.USER_SYSTEM;
12087                }
12088                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
12089                checkTime(startTime, "getContentProviderImpl: got app info for user");
12090
12091                String msg;
12092                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
12093                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
12094                        != null) {
12095                    throw new SecurityException(msg);
12096                }
12097                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
12098
12099                if (!mProcessesReady
12100                        && !cpi.processName.equals("system")) {
12101                    // If this content provider does not run in the system
12102                    // process, and the system is not yet ready to run other
12103                    // processes, then fail fast instead of hanging.
12104                    throw new IllegalArgumentException(
12105                            "Attempt to launch content provider before system ready");
12106                }
12107
12108                // Make sure that the user who owns this provider is running.  If not,
12109                // we don't want to allow it to run.
12110                if (!mUserController.isUserRunning(userId, 0)) {
12111                    Slog.w(TAG, "Unable to launch app "
12112                            + cpi.applicationInfo.packageName + "/"
12113                            + cpi.applicationInfo.uid + " for provider "
12114                            + name + ": user " + userId + " is stopped");
12115                    return null;
12116                }
12117
12118                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
12119                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
12120                cpr = mProviderMap.getProviderByClass(comp, userId);
12121                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
12122                final boolean firstClass = cpr == null;
12123                if (firstClass) {
12124                    final long ident = Binder.clearCallingIdentity();
12125
12126                    // If permissions need a review before any of the app components can run,
12127                    // we return no provider and launch a review activity if the calling app
12128                    // is in the foreground.
12129                    if (mPermissionReviewRequired) {
12130                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
12131                            return null;
12132                        }
12133                    }
12134
12135                    try {
12136                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
12137                        ApplicationInfo ai =
12138                            AppGlobals.getPackageManager().
12139                                getApplicationInfo(
12140                                        cpi.applicationInfo.packageName,
12141                                        STOCK_PM_FLAGS, userId);
12142                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
12143                        if (ai == null) {
12144                            Slog.w(TAG, "No package info for content provider "
12145                                    + cpi.name);
12146                            return null;
12147                        }
12148                        ai = getAppInfoForUser(ai, userId);
12149                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
12150                    } catch (RemoteException ex) {
12151                        // pm is in same process, this will never happen.
12152                    } finally {
12153                        Binder.restoreCallingIdentity(ident);
12154                    }
12155                }
12156
12157                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
12158
12159                if (r != null && cpr.canRunHere(r)) {
12160                    // If this is a multiprocess provider, then just return its
12161                    // info and allow the caller to instantiate it.  Only do
12162                    // this if the provider is the same user as the caller's
12163                    // process, or can run as root (so can be in any process).
12164                    return cpr.newHolder(null);
12165                }
12166
12167                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
12168                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
12169                            + cpr.info.name + " callers=" + Debug.getCallers(6));
12170
12171                // This is single process, and our app is now connecting to it.
12172                // See if we are already in the process of launching this
12173                // provider.
12174                final int N = mLaunchingProviders.size();
12175                int i;
12176                for (i = 0; i < N; i++) {
12177                    if (mLaunchingProviders.get(i) == cpr) {
12178                        break;
12179                    }
12180                }
12181
12182                // If the provider is not already being launched, then get it
12183                // started.
12184                if (i >= N) {
12185                    final long origId = Binder.clearCallingIdentity();
12186
12187                    try {
12188                        // Content provider is now in use, its package can't be stopped.
12189                        try {
12190                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
12191                            AppGlobals.getPackageManager().setPackageStoppedState(
12192                                    cpr.appInfo.packageName, false, userId);
12193                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
12194                        } catch (RemoteException e) {
12195                        } catch (IllegalArgumentException e) {
12196                            Slog.w(TAG, "Failed trying to unstop package "
12197                                    + cpr.appInfo.packageName + ": " + e);
12198                        }
12199
12200                        // Use existing process if already started
12201                        checkTime(startTime, "getContentProviderImpl: looking for process record");
12202                        ProcessRecord proc = getProcessRecordLocked(
12203                                cpi.processName, cpr.appInfo.uid, false);
12204                        if (proc != null && proc.thread != null && !proc.killed) {
12205                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
12206                                    "Installing in existing process " + proc);
12207                            if (!proc.pubProviders.containsKey(cpi.name)) {
12208                                checkTime(startTime, "getContentProviderImpl: scheduling install");
12209                                proc.pubProviders.put(cpi.name, cpr);
12210                                try {
12211                                    proc.thread.scheduleInstallProvider(cpi);
12212                                } catch (RemoteException e) {
12213                                }
12214                            }
12215                        } else {
12216                            checkTime(startTime, "getContentProviderImpl: before start process");
12217                            proc = startProcessLocked(cpi.processName,
12218                                    cpr.appInfo, false, 0, "content provider",
12219                                    new ComponentName(cpi.applicationInfo.packageName,
12220                                            cpi.name), false, false, false);
12221                            checkTime(startTime, "getContentProviderImpl: after start process");
12222                            if (proc == null) {
12223                                Slog.w(TAG, "Unable to launch app "
12224                                        + cpi.applicationInfo.packageName + "/"
12225                                        + cpi.applicationInfo.uid + " for provider "
12226                                        + name + ": process is bad");
12227                                return null;
12228                            }
12229                        }
12230                        cpr.launchingApp = proc;
12231                        mLaunchingProviders.add(cpr);
12232                    } finally {
12233                        Binder.restoreCallingIdentity(origId);
12234                    }
12235                }
12236
12237                checkTime(startTime, "getContentProviderImpl: updating data structures");
12238
12239                // Make sure the provider is published (the same provider class
12240                // may be published under multiple names).
12241                if (firstClass) {
12242                    mProviderMap.putProviderByClass(comp, cpr);
12243                }
12244
12245                mProviderMap.putProviderByName(name, cpr);
12246                conn = incProviderCountLocked(r, cpr, token, stable);
12247                if (conn != null) {
12248                    conn.waiting = true;
12249                }
12250            }
12251            checkTime(startTime, "getContentProviderImpl: done!");
12252
12253            grantEphemeralAccessLocked(userId, null /*intent*/,
12254                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
12255        }
12256
12257        // Wait for the provider to be published...
12258        synchronized (cpr) {
12259            while (cpr.provider == null) {
12260                if (cpr.launchingApp == null) {
12261                    Slog.w(TAG, "Unable to launch app "
12262                            + cpi.applicationInfo.packageName + "/"
12263                            + cpi.applicationInfo.uid + " for provider "
12264                            + name + ": launching app became null");
12265                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
12266                            UserHandle.getUserId(cpi.applicationInfo.uid),
12267                            cpi.applicationInfo.packageName,
12268                            cpi.applicationInfo.uid, name);
12269                    return null;
12270                }
12271                try {
12272                    if (DEBUG_MU) Slog.v(TAG_MU,
12273                            "Waiting to start provider " + cpr
12274                            + " launchingApp=" + cpr.launchingApp);
12275                    if (conn != null) {
12276                        conn.waiting = true;
12277                    }
12278                    cpr.wait();
12279                } catch (InterruptedException ex) {
12280                } finally {
12281                    if (conn != null) {
12282                        conn.waiting = false;
12283                    }
12284                }
12285            }
12286        }
12287        return cpr != null ? cpr.newHolder(conn) : null;
12288    }
12289
12290    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
12291            ProcessRecord r, final int userId) {
12292        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
12293                cpi.packageName, userId)) {
12294
12295            final boolean callerForeground = r == null || r.setSchedGroup
12296                    != ProcessList.SCHED_GROUP_BACKGROUND;
12297
12298            // Show a permission review UI only for starting from a foreground app
12299            if (!callerForeground) {
12300                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
12301                        + cpi.packageName + " requires a permissions review");
12302                return false;
12303            }
12304
12305            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
12306            intent.addFlags(FLAG_ACTIVITY_NEW_TASK
12307                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
12308            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
12309
12310            if (DEBUG_PERMISSIONS_REVIEW) {
12311                Slog.i(TAG, "u" + userId + " Launching permission review "
12312                        + "for package " + cpi.packageName);
12313            }
12314
12315            final UserHandle userHandle = new UserHandle(userId);
12316            mHandler.post(new Runnable() {
12317                @Override
12318                public void run() {
12319                    mContext.startActivityAsUser(intent, userHandle);
12320                }
12321            });
12322
12323            return false;
12324        }
12325
12326        return true;
12327    }
12328
12329    /**
12330     * Returns the PackageManager. Used by classes hosted by {@link ActivityManagerService}. The
12331     * PackageManager could be unavailable at construction time and therefore needs to be accessed
12332     * on demand.
12333     */
12334    IPackageManager getPackageManager() {
12335        return AppGlobals.getPackageManager();
12336    }
12337
12338    ActivityStartController getActivityStartController() {
12339        return mActivityStartController;
12340    }
12341
12342    PackageManagerInternal getPackageManagerInternalLocked() {
12343        if (mPackageManagerInt == null) {
12344            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
12345        }
12346        return mPackageManagerInt;
12347    }
12348
12349    @Override
12350    public final ContentProviderHolder getContentProvider(
12351            IApplicationThread caller, String name, int userId, boolean stable) {
12352        enforceNotIsolatedCaller("getContentProvider");
12353        if (caller == null) {
12354            String msg = "null IApplicationThread when getting content provider "
12355                    + name;
12356            Slog.w(TAG, msg);
12357            throw new SecurityException(msg);
12358        }
12359        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
12360        // with cross-user grant.
12361        return getContentProviderImpl(caller, name, null, stable, userId);
12362    }
12363
12364    public ContentProviderHolder getContentProviderExternal(
12365            String name, int userId, IBinder token) {
12366        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12367            "Do not have permission in call getContentProviderExternal()");
12368        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12369                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
12370        return getContentProviderExternalUnchecked(name, token, userId);
12371    }
12372
12373    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
12374            IBinder token, int userId) {
12375        return getContentProviderImpl(null, name, token, true, userId);
12376    }
12377
12378    /**
12379     * Drop a content provider from a ProcessRecord's bookkeeping
12380     */
12381    public void removeContentProvider(IBinder connection, boolean stable) {
12382        enforceNotIsolatedCaller("removeContentProvider");
12383        long ident = Binder.clearCallingIdentity();
12384        try {
12385            synchronized (this) {
12386                ContentProviderConnection conn;
12387                try {
12388                    conn = (ContentProviderConnection)connection;
12389                } catch (ClassCastException e) {
12390                    String msg ="removeContentProvider: " + connection
12391                            + " not a ContentProviderConnection";
12392                    Slog.w(TAG, msg);
12393                    throw new IllegalArgumentException(msg);
12394                }
12395                if (conn == null) {
12396                    throw new NullPointerException("connection is null");
12397                }
12398                if (decProviderCountLocked(conn, null, null, stable)) {
12399                    updateOomAdjLocked();
12400                }
12401            }
12402        } finally {
12403            Binder.restoreCallingIdentity(ident);
12404        }
12405    }
12406
12407    public void removeContentProviderExternal(String name, IBinder token) {
12408        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
12409            "Do not have permission in call removeContentProviderExternal()");
12410        int userId = UserHandle.getCallingUserId();
12411        long ident = Binder.clearCallingIdentity();
12412        try {
12413            removeContentProviderExternalUnchecked(name, token, userId);
12414        } finally {
12415            Binder.restoreCallingIdentity(ident);
12416        }
12417    }
12418
12419    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
12420        synchronized (this) {
12421            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
12422            if(cpr == null) {
12423                //remove from mProvidersByClass
12424                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
12425                return;
12426            }
12427
12428            //update content provider record entry info
12429            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
12430            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
12431            if (localCpr.hasExternalProcessHandles()) {
12432                if (localCpr.removeExternalProcessHandleLocked(token)) {
12433                    updateOomAdjLocked();
12434                } else {
12435                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
12436                            + " with no external reference for token: "
12437                            + token + ".");
12438                }
12439            } else {
12440                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
12441                        + " with no external references.");
12442            }
12443        }
12444    }
12445
12446    public final void publishContentProviders(IApplicationThread caller,
12447            List<ContentProviderHolder> providers) {
12448        if (providers == null) {
12449            return;
12450        }
12451
12452        enforceNotIsolatedCaller("publishContentProviders");
12453        synchronized (this) {
12454            final ProcessRecord r = getRecordForAppLocked(caller);
12455            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
12456            if (r == null) {
12457                throw new SecurityException(
12458                        "Unable to find app for caller " + caller
12459                      + " (pid=" + Binder.getCallingPid()
12460                      + ") when publishing content providers");
12461            }
12462
12463            final long origId = Binder.clearCallingIdentity();
12464
12465            final int N = providers.size();
12466            for (int i = 0; i < N; i++) {
12467                ContentProviderHolder src = providers.get(i);
12468                if (src == null || src.info == null || src.provider == null) {
12469                    continue;
12470                }
12471                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
12472                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
12473                if (dst != null) {
12474                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
12475                    mProviderMap.putProviderByClass(comp, dst);
12476                    String names[] = dst.info.authority.split(";");
12477                    for (int j = 0; j < names.length; j++) {
12478                        mProviderMap.putProviderByName(names[j], dst);
12479                    }
12480
12481                    int launchingCount = mLaunchingProviders.size();
12482                    int j;
12483                    boolean wasInLaunchingProviders = false;
12484                    for (j = 0; j < launchingCount; j++) {
12485                        if (mLaunchingProviders.get(j) == dst) {
12486                            mLaunchingProviders.remove(j);
12487                            wasInLaunchingProviders = true;
12488                            j--;
12489                            launchingCount--;
12490                        }
12491                    }
12492                    if (wasInLaunchingProviders) {
12493                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12494                    }
12495                    synchronized (dst) {
12496                        dst.provider = src.provider;
12497                        dst.proc = r;
12498                        dst.notifyAll();
12499                    }
12500                    updateOomAdjLocked(r, true);
12501                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12502                            src.info.authority);
12503                }
12504            }
12505
12506            Binder.restoreCallingIdentity(origId);
12507        }
12508    }
12509
12510    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12511        ContentProviderConnection conn;
12512        try {
12513            conn = (ContentProviderConnection)connection;
12514        } catch (ClassCastException e) {
12515            String msg ="refContentProvider: " + connection
12516                    + " not a ContentProviderConnection";
12517            Slog.w(TAG, msg);
12518            throw new IllegalArgumentException(msg);
12519        }
12520        if (conn == null) {
12521            throw new NullPointerException("connection is null");
12522        }
12523
12524        synchronized (this) {
12525            if (stable > 0) {
12526                conn.numStableIncs += stable;
12527            }
12528            stable = conn.stableCount + stable;
12529            if (stable < 0) {
12530                throw new IllegalStateException("stableCount < 0: " + stable);
12531            }
12532
12533            if (unstable > 0) {
12534                conn.numUnstableIncs += unstable;
12535            }
12536            unstable = conn.unstableCount + unstable;
12537            if (unstable < 0) {
12538                throw new IllegalStateException("unstableCount < 0: " + unstable);
12539            }
12540
12541            if ((stable+unstable) <= 0) {
12542                throw new IllegalStateException("ref counts can't go to zero here: stable="
12543                        + stable + " unstable=" + unstable);
12544            }
12545            conn.stableCount = stable;
12546            conn.unstableCount = unstable;
12547            return !conn.dead;
12548        }
12549    }
12550
12551    public void unstableProviderDied(IBinder connection) {
12552        ContentProviderConnection conn;
12553        try {
12554            conn = (ContentProviderConnection)connection;
12555        } catch (ClassCastException e) {
12556            String msg ="refContentProvider: " + connection
12557                    + " not a ContentProviderConnection";
12558            Slog.w(TAG, msg);
12559            throw new IllegalArgumentException(msg);
12560        }
12561        if (conn == null) {
12562            throw new NullPointerException("connection is null");
12563        }
12564
12565        // Safely retrieve the content provider associated with the connection.
12566        IContentProvider provider;
12567        synchronized (this) {
12568            provider = conn.provider.provider;
12569        }
12570
12571        if (provider == null) {
12572            // Um, yeah, we're way ahead of you.
12573            return;
12574        }
12575
12576        // Make sure the caller is being honest with us.
12577        if (provider.asBinder().pingBinder()) {
12578            // Er, no, still looks good to us.
12579            synchronized (this) {
12580                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12581                        + " says " + conn + " died, but we don't agree");
12582                return;
12583            }
12584        }
12585
12586        // Well look at that!  It's dead!
12587        synchronized (this) {
12588            if (conn.provider.provider != provider) {
12589                // But something changed...  good enough.
12590                return;
12591            }
12592
12593            ProcessRecord proc = conn.provider.proc;
12594            if (proc == null || proc.thread == null) {
12595                // Seems like the process is already cleaned up.
12596                return;
12597            }
12598
12599            // As far as we're concerned, this is just like receiving a
12600            // death notification...  just a bit prematurely.
12601            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12602                    + ") early provider death");
12603            final long ident = Binder.clearCallingIdentity();
12604            try {
12605                appDiedLocked(proc);
12606            } finally {
12607                Binder.restoreCallingIdentity(ident);
12608            }
12609        }
12610    }
12611
12612    @Override
12613    public void appNotRespondingViaProvider(IBinder connection) {
12614        enforceCallingPermission(REMOVE_TASKS, "appNotRespondingViaProvider()");
12615
12616        final ContentProviderConnection conn = (ContentProviderConnection) connection;
12617        if (conn == null) {
12618            Slog.w(TAG, "ContentProviderConnection is null");
12619            return;
12620        }
12621
12622        final ProcessRecord host = conn.provider.proc;
12623        if (host == null) {
12624            Slog.w(TAG, "Failed to find hosting ProcessRecord");
12625            return;
12626        }
12627
12628        mHandler.post(new Runnable() {
12629            @Override
12630            public void run() {
12631                mAppErrors.appNotResponding(host, null, null, false,
12632                        "ContentProvider not responding");
12633            }
12634        });
12635    }
12636
12637    public final void installSystemProviders() {
12638        List<ProviderInfo> providers;
12639        synchronized (this) {
12640            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12641            providers = generateApplicationProvidersLocked(app);
12642            if (providers != null) {
12643                for (int i=providers.size()-1; i>=0; i--) {
12644                    ProviderInfo pi = (ProviderInfo)providers.get(i);
12645                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12646                        Slog.w(TAG, "Not installing system proc provider " + pi.name
12647                                + ": not system .apk");
12648                        providers.remove(i);
12649                    }
12650                }
12651            }
12652        }
12653        if (providers != null) {
12654            mSystemThread.installSystemProviders(providers);
12655        }
12656
12657        mConstants.start(mContext.getContentResolver());
12658        mCoreSettingsObserver = new CoreSettingsObserver(this);
12659        mFontScaleSettingObserver = new FontScaleSettingObserver();
12660        mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
12661        GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
12662
12663        // Now that the settings provider is published we can consider sending
12664        // in a rescue party.
12665        RescueParty.onSettingsProviderPublished(mContext);
12666
12667        //mUsageStatsService.monitorPackages();
12668    }
12669
12670    void startPersistentApps(int matchFlags) {
12671        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12672
12673        synchronized (this) {
12674            try {
12675                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12676                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12677                for (ApplicationInfo app : apps) {
12678                    if (!"android".equals(app.packageName)) {
12679                        addAppLocked(app, null, false, null /* ABI override */);
12680                    }
12681                }
12682            } catch (RemoteException ex) {
12683            }
12684        }
12685    }
12686
12687    /**
12688     * When a user is unlocked, we need to install encryption-unaware providers
12689     * belonging to any running apps.
12690     */
12691    void installEncryptionUnawareProviders(int userId) {
12692        // We're only interested in providers that are encryption unaware, and
12693        // we don't care about uninstalled apps, since there's no way they're
12694        // running at this point.
12695        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12696
12697        synchronized (this) {
12698            final int NP = mProcessNames.getMap().size();
12699            for (int ip = 0; ip < NP; ip++) {
12700                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12701                final int NA = apps.size();
12702                for (int ia = 0; ia < NA; ia++) {
12703                    final ProcessRecord app = apps.valueAt(ia);
12704                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12705
12706                    final int NG = app.pkgList.size();
12707                    for (int ig = 0; ig < NG; ig++) {
12708                        try {
12709                            final String pkgName = app.pkgList.keyAt(ig);
12710                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12711                                    .getPackageInfo(pkgName, matchFlags, userId);
12712                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12713                                for (ProviderInfo pi : pkgInfo.providers) {
12714                                    // TODO: keep in sync with generateApplicationProvidersLocked
12715                                    final boolean processMatch = Objects.equals(pi.processName,
12716                                            app.processName) || pi.multiprocess;
12717                                    final boolean userMatch = isSingleton(pi.processName,
12718                                            pi.applicationInfo, pi.name, pi.flags)
12719                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12720                                    if (processMatch && userMatch) {
12721                                        Log.v(TAG, "Installing " + pi);
12722                                        app.thread.scheduleInstallProvider(pi);
12723                                    } else {
12724                                        Log.v(TAG, "Skipping " + pi);
12725                                    }
12726                                }
12727                            }
12728                        } catch (RemoteException ignored) {
12729                        }
12730                    }
12731                }
12732            }
12733        }
12734    }
12735
12736    /**
12737     * Allows apps to retrieve the MIME type of a URI.
12738     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12739     * users, then it does not need permission to access the ContentProvider.
12740     * Either, it needs cross-user uri grants.
12741     *
12742     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12743     *
12744     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12745     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12746     */
12747    public String getProviderMimeType(Uri uri, int userId) {
12748        enforceNotIsolatedCaller("getProviderMimeType");
12749        final String name = uri.getAuthority();
12750        int callingUid = Binder.getCallingUid();
12751        int callingPid = Binder.getCallingPid();
12752        long ident = 0;
12753        boolean clearedIdentity = false;
12754        userId = mUserController.unsafeConvertIncomingUser(userId);
12755        if (canClearIdentity(callingPid, callingUid, userId)) {
12756            clearedIdentity = true;
12757            ident = Binder.clearCallingIdentity();
12758        }
12759        ContentProviderHolder holder = null;
12760        try {
12761            holder = getContentProviderExternalUnchecked(name, null, userId);
12762            if (holder != null) {
12763                return holder.provider.getType(uri);
12764            }
12765        } catch (RemoteException e) {
12766            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12767            return null;
12768        } catch (Exception e) {
12769            Log.w(TAG, "Exception while determining type of " + uri, e);
12770            return null;
12771        } finally {
12772            // We need to clear the identity to call removeContentProviderExternalUnchecked
12773            if (!clearedIdentity) {
12774                ident = Binder.clearCallingIdentity();
12775            }
12776            try {
12777                if (holder != null) {
12778                    removeContentProviderExternalUnchecked(name, null, userId);
12779                }
12780            } finally {
12781                Binder.restoreCallingIdentity(ident);
12782            }
12783        }
12784
12785        return null;
12786    }
12787
12788    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12789        if (UserHandle.getUserId(callingUid) == userId) {
12790            return true;
12791        }
12792        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12793                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12794                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12795                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12796                return true;
12797        }
12798        return false;
12799    }
12800
12801    // =========================================================
12802    // GLOBAL MANAGEMENT
12803    // =========================================================
12804
12805    @GuardedBy("this")
12806    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12807            boolean isolated, int isolatedUid) {
12808        String proc = customProcess != null ? customProcess : info.processName;
12809        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12810        final int userId = UserHandle.getUserId(info.uid);
12811        int uid = info.uid;
12812        if (isolated) {
12813            if (isolatedUid == 0) {
12814                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12815                while (true) {
12816                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12817                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12818                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12819                    }
12820                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12821                    mNextIsolatedProcessUid++;
12822                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12823                        // No process for this uid, use it.
12824                        break;
12825                    }
12826                    stepsLeft--;
12827                    if (stepsLeft <= 0) {
12828                        return null;
12829                    }
12830                }
12831            } else {
12832                // Special case for startIsolatedProcess (internal only), where
12833                // the uid of the isolated process is specified by the caller.
12834                uid = isolatedUid;
12835            }
12836            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12837
12838            // Register the isolated UID with this application so BatteryStats knows to
12839            // attribute resource usage to the application.
12840            //
12841            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12842            // about the process state of the isolated UID *before* it is registered with the
12843            // owning application.
12844            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12845        }
12846        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12847        if (!mBooted && !mBooting
12848                && userId == UserHandle.USER_SYSTEM
12849                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12850            // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
12851            r.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
12852            r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
12853            r.persistent = true;
12854            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12855        }
12856        if (isolated && isolatedUid != 0) {
12857            // Special case for startIsolatedProcess (internal only) - assume the process
12858            // is required by the system server to prevent it being killed.
12859            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
12860        }
12861        addProcessNameLocked(r);
12862        return r;
12863    }
12864
12865    private boolean uidOnBackgroundWhitelist(final int uid) {
12866        final int appId = UserHandle.getAppId(uid);
12867        final int[] whitelist = mBackgroundAppIdWhitelist;
12868        final int N = whitelist.length;
12869        for (int i = 0; i < N; i++) {
12870            if (appId == whitelist[i]) {
12871                return true;
12872            }
12873        }
12874        return false;
12875    }
12876
12877    @Override
12878    public void backgroundWhitelistUid(final int uid) {
12879        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12880            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12881        }
12882
12883        if (DEBUG_BACKGROUND_CHECK) {
12884            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12885        }
12886        synchronized (this) {
12887            final int N = mBackgroundAppIdWhitelist.length;
12888            int[] newList = new int[N+1];
12889            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12890            newList[N] = UserHandle.getAppId(uid);
12891            mBackgroundAppIdWhitelist = newList;
12892        }
12893    }
12894
12895    @GuardedBy("this")
12896    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12897            String abiOverride) {
12898        return addAppLocked(info, customProcess, isolated, false /* disableHiddenApiChecks */,
12899                abiOverride);
12900    }
12901
12902    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12903            boolean disableHiddenApiChecks, String abiOverride) {
12904        ProcessRecord app;
12905        if (!isolated) {
12906            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12907                    info.uid, true);
12908        } else {
12909            app = null;
12910        }
12911
12912        if (app == null) {
12913            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12914            updateLruProcessLocked(app, false, null);
12915            updateOomAdjLocked();
12916        }
12917
12918        // This package really, really can not be stopped.
12919        try {
12920            AppGlobals.getPackageManager().setPackageStoppedState(
12921                    info.packageName, false, UserHandle.getUserId(app.uid));
12922        } catch (RemoteException e) {
12923        } catch (IllegalArgumentException e) {
12924            Slog.w(TAG, "Failed trying to unstop package "
12925                    + info.packageName + ": " + e);
12926        }
12927
12928        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12929            app.persistent = true;
12930            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12931        }
12932        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12933            mPersistentStartingProcesses.add(app);
12934            startProcessLocked(app, "added application",
12935                    customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
12936                    abiOverride);
12937        }
12938
12939        return app;
12940    }
12941
12942    public void unhandledBack() {
12943        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12944                "unhandledBack()");
12945
12946        synchronized(this) {
12947            final long origId = Binder.clearCallingIdentity();
12948            try {
12949                getFocusedStack().unhandledBackLocked();
12950            } finally {
12951                Binder.restoreCallingIdentity(origId);
12952            }
12953        }
12954    }
12955
12956    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12957        enforceNotIsolatedCaller("openContentUri");
12958        final int userId = UserHandle.getCallingUserId();
12959        final Uri uri = Uri.parse(uriString);
12960        String name = uri.getAuthority();
12961        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12962        ParcelFileDescriptor pfd = null;
12963        if (cph != null) {
12964            // We record the binder invoker's uid in thread-local storage before
12965            // going to the content provider to open the file.  Later, in the code
12966            // that handles all permissions checks, we look for this uid and use
12967            // that rather than the Activity Manager's own uid.  The effect is that
12968            // we do the check against the caller's permissions even though it looks
12969            // to the content provider like the Activity Manager itself is making
12970            // the request.
12971            Binder token = new Binder();
12972            sCallerIdentity.set(new Identity(
12973                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12974            try {
12975                pfd = cph.provider.openFile(null, uri, "r", null, token);
12976            } catch (FileNotFoundException e) {
12977                // do nothing; pfd will be returned null
12978            } finally {
12979                // Ensure that whatever happens, we clean up the identity state
12980                sCallerIdentity.remove();
12981                // Ensure we're done with the provider.
12982                removeContentProviderExternalUnchecked(name, null, userId);
12983            }
12984        } else {
12985            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12986        }
12987        return pfd;
12988    }
12989
12990    // Actually is sleeping or shutting down or whatever else in the future
12991    // is an inactive state.
12992    boolean isSleepingOrShuttingDownLocked() {
12993        return isSleepingLocked() || mShuttingDown;
12994    }
12995
12996    boolean isShuttingDownLocked() {
12997        return mShuttingDown;
12998    }
12999
13000    boolean isSleepingLocked() {
13001        return mSleeping;
13002    }
13003
13004    void onWakefulnessChanged(int wakefulness) {
13005        synchronized(this) {
13006            boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13007            boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
13008            mWakefulness = wakefulness;
13009
13010            if (wasAwake != isAwake) {
13011                // Also update state in a special way for running foreground services UI.
13012                mServices.updateScreenStateLocked(isAwake);
13013                mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
13014                        .sendToTarget();
13015            }
13016        }
13017    }
13018
13019    @GuardedBy("this")
13020    void finishRunningVoiceLocked() {
13021        if (mRunningVoice != null) {
13022            mRunningVoice = null;
13023            mVoiceWakeLock.release();
13024            updateSleepIfNeededLocked();
13025        }
13026    }
13027
13028    void startTimeTrackingFocusedActivityLocked() {
13029        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
13030        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
13031            mCurAppTimeTracker.start(resumedActivity.packageName);
13032        }
13033    }
13034
13035    @GuardedBy("this")
13036    void updateSleepIfNeededLocked() {
13037        final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
13038        final boolean wasSleeping = mSleeping;
13039
13040        if (!shouldSleep) {
13041            // If wasSleeping is true, we need to wake up activity manager state from when
13042            // we started sleeping. In either case, we need to apply the sleep tokens, which
13043            // will wake up stacks or put them to sleep as appropriate.
13044            if (wasSleeping) {
13045                mSleeping = false;
13046                startTimeTrackingFocusedActivityLocked();
13047                mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
13048                mStackSupervisor.comeOutOfSleepIfNeededLocked();
13049            }
13050            mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
13051            if (wasSleeping) {
13052                updateOomAdjLocked();
13053            }
13054        } else if (!mSleeping && shouldSleep) {
13055            mSleeping = true;
13056            if (mCurAppTimeTracker != null) {
13057                mCurAppTimeTracker.stop();
13058            }
13059            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
13060            mStackSupervisor.goingToSleepLocked();
13061            updateOomAdjLocked();
13062        }
13063    }
13064
13065    /** Pokes the task persister. */
13066    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
13067        mRecentTasks.notifyTaskPersisterLocked(task, flush);
13068    }
13069
13070    /**
13071     * Notifies all listeners when the pinned stack animation starts.
13072     */
13073    @Override
13074    public void notifyPinnedStackAnimationStarted() {
13075        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
13076    }
13077
13078    /**
13079     * Notifies all listeners when the pinned stack animation ends.
13080     */
13081    @Override
13082    public void notifyPinnedStackAnimationEnded() {
13083        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
13084    }
13085
13086    @Override
13087    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
13088        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
13089    }
13090
13091    @Override
13092    public boolean shutdown(int timeout) {
13093        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
13094                != PackageManager.PERMISSION_GRANTED) {
13095            throw new SecurityException("Requires permission "
13096                    + android.Manifest.permission.SHUTDOWN);
13097        }
13098
13099        // TODO: Where should the corresponding '1' (start) write go?
13100        StatsLog.write(StatsLog.DEVICE_ON_STATUS_CHANGED,
13101                StatsLog.DEVICE_ON_STATUS_CHANGED__STATE__OFF);
13102
13103        boolean timedout = false;
13104
13105        synchronized(this) {
13106            mShuttingDown = true;
13107            mStackSupervisor.prepareForShutdownLocked();
13108            updateEventDispatchingLocked();
13109            timedout = mStackSupervisor.shutdownLocked(timeout);
13110        }
13111
13112        mAppOpsService.shutdown();
13113        if (mUsageStatsService != null) {
13114            mUsageStatsService.prepareShutdown();
13115        }
13116        mBatteryStatsService.shutdown();
13117        synchronized (this) {
13118            mProcessStats.shutdownLocked();
13119            notifyTaskPersisterLocked(null, true);
13120        }
13121
13122        return timedout;
13123    }
13124
13125    public final void activitySlept(IBinder token) {
13126        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
13127
13128        final long origId = Binder.clearCallingIdentity();
13129
13130        synchronized (this) {
13131            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13132            if (r != null) {
13133                mStackSupervisor.activitySleptLocked(r);
13134            }
13135        }
13136
13137        Binder.restoreCallingIdentity(origId);
13138    }
13139
13140    @GuardedBy("this")
13141    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
13142        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
13143        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
13144        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
13145            boolean wasRunningVoice = mRunningVoice != null;
13146            mRunningVoice = session;
13147            if (!wasRunningVoice) {
13148                mVoiceWakeLock.acquire();
13149                updateSleepIfNeededLocked();
13150            }
13151        }
13152    }
13153
13154    private void updateEventDispatchingLocked() {
13155        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
13156    }
13157
13158    @Override
13159    public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
13160        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
13161                != PackageManager.PERMISSION_GRANTED) {
13162            throw new SecurityException("Requires permission "
13163                    + android.Manifest.permission.DEVICE_POWER);
13164        }
13165
13166        synchronized(this) {
13167            long ident = Binder.clearCallingIdentity();
13168            try {
13169                mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
13170            } finally {
13171                Binder.restoreCallingIdentity(ident);
13172            }
13173        }
13174
13175        mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
13176                .sendToTarget();
13177    }
13178
13179    @Override
13180    public void notifyLockedProfile(@UserIdInt int userId) {
13181        try {
13182            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
13183                throw new SecurityException("Only privileged app can call notifyLockedProfile");
13184            }
13185        } catch (RemoteException ex) {
13186            throw new SecurityException("Fail to check is caller a privileged app", ex);
13187        }
13188
13189        synchronized (this) {
13190            final long ident = Binder.clearCallingIdentity();
13191            try {
13192                if (mUserController.shouldConfirmCredentials(userId)) {
13193                    if (mKeyguardController.isKeyguardLocked()) {
13194                        // Showing launcher to avoid user entering credential twice.
13195                        final int currentUserId = mUserController.getCurrentUserId();
13196                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
13197                    }
13198                    mStackSupervisor.lockAllProfileTasks(userId);
13199                }
13200            } finally {
13201                Binder.restoreCallingIdentity(ident);
13202            }
13203        }
13204    }
13205
13206    @Override
13207    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
13208        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
13209        synchronized (this) {
13210            final long ident = Binder.clearCallingIdentity();
13211            try {
13212                intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
13213                        FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
13214                        FLAG_ACTIVITY_TASK_ON_HOME);
13215                ActivityOptions activityOptions = options != null
13216                        ? new ActivityOptions(options)
13217                        : ActivityOptions.makeBasic();
13218                activityOptions.setLaunchTaskId(
13219                        mStackSupervisor.getHomeActivity().getTask().taskId);
13220                mContext.startActivityAsUser(intent, activityOptions.toBundle(),
13221                        UserHandle.CURRENT);
13222            } finally {
13223                Binder.restoreCallingIdentity(ident);
13224            }
13225        }
13226    }
13227
13228    @Override
13229    public void stopAppSwitches() {
13230        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
13231                != PackageManager.PERMISSION_GRANTED) {
13232            throw new SecurityException("viewquires permission "
13233                    + android.Manifest.permission.STOP_APP_SWITCHES);
13234        }
13235
13236        synchronized(this) {
13237            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
13238                    + APP_SWITCH_DELAY_TIME;
13239            mDidAppSwitch = false;
13240            mActivityStartController.schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
13241        }
13242    }
13243
13244    public void resumeAppSwitches() {
13245        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
13246                != PackageManager.PERMISSION_GRANTED) {
13247            throw new SecurityException("Requires permission "
13248                    + android.Manifest.permission.STOP_APP_SWITCHES);
13249        }
13250
13251        synchronized(this) {
13252            // Note that we don't execute any pending app switches... we will
13253            // let those wait until either the timeout, or the next start
13254            // activity request.
13255            mAppSwitchesAllowedTime = 0;
13256        }
13257    }
13258
13259    boolean checkAllowAppSwitchUid(int uid) {
13260        ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
13261        if (types != null) {
13262            for (int i = types.size() - 1; i >= 0; i--) {
13263                if (types.valueAt(i).intValue() == uid) {
13264                    return true;
13265                }
13266            }
13267        }
13268        return false;
13269    }
13270
13271    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
13272            int callingPid, int callingUid, String name) {
13273        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
13274            return true;
13275        }
13276
13277        int perm = checkComponentPermission(
13278                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
13279                sourceUid, -1, true);
13280        if (perm == PackageManager.PERMISSION_GRANTED) {
13281            return true;
13282        }
13283        if (checkAllowAppSwitchUid(sourceUid)) {
13284            return true;
13285        }
13286
13287        // If the actual IPC caller is different from the logical source, then
13288        // also see if they are allowed to control app switches.
13289        if (callingUid != -1 && callingUid != sourceUid) {
13290            perm = checkComponentPermission(
13291                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
13292                    callingUid, -1, true);
13293            if (perm == PackageManager.PERMISSION_GRANTED) {
13294                return true;
13295            }
13296            if (checkAllowAppSwitchUid(callingUid)) {
13297                return true;
13298            }
13299        }
13300
13301        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
13302        return false;
13303    }
13304
13305    public void setDebugApp(String packageName, boolean waitForDebugger,
13306            boolean persistent) {
13307        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
13308                "setDebugApp()");
13309
13310        long ident = Binder.clearCallingIdentity();
13311        try {
13312            // Note that this is not really thread safe if there are multiple
13313            // callers into it at the same time, but that's not a situation we
13314            // care about.
13315            if (persistent) {
13316                final ContentResolver resolver = mContext.getContentResolver();
13317                Settings.Global.putString(
13318                    resolver, Settings.Global.DEBUG_APP,
13319                    packageName);
13320                Settings.Global.putInt(
13321                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
13322                    waitForDebugger ? 1 : 0);
13323            }
13324
13325            synchronized (this) {
13326                if (!persistent) {
13327                    mOrigDebugApp = mDebugApp;
13328                    mOrigWaitForDebugger = mWaitForDebugger;
13329                }
13330                mDebugApp = packageName;
13331                mWaitForDebugger = waitForDebugger;
13332                mDebugTransient = !persistent;
13333                if (packageName != null) {
13334                    forceStopPackageLocked(packageName, -1, false, false, true, true,
13335                            false, UserHandle.USER_ALL, "set debug app");
13336                }
13337            }
13338        } finally {
13339            Binder.restoreCallingIdentity(ident);
13340        }
13341    }
13342
13343    /**
13344     * Set or remove an agent to be run whenever an app with the given process name starts.
13345     *
13346     * This method will not check whether the given process name matches a debuggable app. That
13347     * would require scanning all current packages, and a rescan when new packages are installed
13348     * or updated.
13349     *
13350     * Instead, do the check when an application is started and matched to a stored agent.
13351     *
13352     * @param packageName the process name of the app.
13353     * @param agent the agent string to be used, or null to remove any previously set agent.
13354     */
13355    @Override
13356    public void setAgentApp(@NonNull String packageName, @Nullable String agent) {
13357        synchronized (this) {
13358            // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13359            // its own permission.
13360            if (checkCallingPermission(
13361                    android.Manifest.permission.SET_ACTIVITY_WATCHER) !=
13362                        PackageManager.PERMISSION_GRANTED) {
13363                throw new SecurityException(
13364                        "Requires permission " + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13365            }
13366
13367            if (agent == null) {
13368                if (mAppAgentMap != null) {
13369                    mAppAgentMap.remove(packageName);
13370                    if (mAppAgentMap.isEmpty()) {
13371                        mAppAgentMap = null;
13372                    }
13373                }
13374            } else {
13375                if (mAppAgentMap == null) {
13376                    mAppAgentMap = new HashMap<>();
13377                }
13378                if (mAppAgentMap.size() >= 100) {
13379                    // Limit the size of the map, to avoid OOMEs.
13380                    Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName
13381                            + "/" + agent);
13382                    return;
13383                }
13384                mAppAgentMap.put(packageName, agent);
13385            }
13386        }
13387    }
13388
13389    void setTrackAllocationApp(ApplicationInfo app, String processName) {
13390        synchronized (this) {
13391            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13392            if (!isDebuggable) {
13393                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13394                    throw new SecurityException("Process not debuggable: " + app.packageName);
13395                }
13396            }
13397
13398            mTrackAllocationApp = processName;
13399        }
13400    }
13401
13402    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
13403        synchronized (this) {
13404            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13405            if (!isDebuggable) {
13406                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13407                    throw new SecurityException("Process not debuggable: " + app.packageName);
13408                }
13409            }
13410            mProfileApp = processName;
13411
13412            if (mProfilerInfo != null) {
13413                if (mProfilerInfo.profileFd != null) {
13414                    try {
13415                        mProfilerInfo.profileFd.close();
13416                    } catch (IOException e) {
13417                    }
13418                }
13419            }
13420            mProfilerInfo = new ProfilerInfo(profilerInfo);
13421            mProfileType = 0;
13422        }
13423    }
13424
13425    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
13426        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13427        if (!isDebuggable) {
13428            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13429                throw new SecurityException("Process not debuggable: " + app.packageName);
13430            }
13431        }
13432        mNativeDebuggingApp = processName;
13433    }
13434
13435    @Override
13436    public void setAlwaysFinish(boolean enabled) {
13437        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
13438                "setAlwaysFinish()");
13439
13440        long ident = Binder.clearCallingIdentity();
13441        try {
13442            Settings.Global.putInt(
13443                    mContext.getContentResolver(),
13444                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
13445
13446            synchronized (this) {
13447                mAlwaysFinishActivities = enabled;
13448            }
13449        } finally {
13450            Binder.restoreCallingIdentity(ident);
13451        }
13452    }
13453
13454    @Override
13455    public void setActivityController(IActivityController controller, boolean imAMonkey) {
13456        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13457                "setActivityController()");
13458        synchronized (this) {
13459            mController = controller;
13460            mControllerIsAMonkey = imAMonkey;
13461            Watchdog.getInstance().setActivityController(controller);
13462        }
13463    }
13464
13465    @Override
13466    public void setUserIsMonkey(boolean userIsMonkey) {
13467        synchronized (this) {
13468            synchronized (mPidsSelfLocked) {
13469                final int callingPid = Binder.getCallingPid();
13470                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
13471                if (proc == null) {
13472                    throw new SecurityException("Unknown process: " + callingPid);
13473                }
13474                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
13475                    throw new SecurityException("Only an instrumentation process "
13476                            + "with a UiAutomation can call setUserIsMonkey");
13477                }
13478            }
13479            mUserIsMonkey = userIsMonkey;
13480        }
13481    }
13482
13483    @Override
13484    public boolean isUserAMonkey() {
13485        synchronized (this) {
13486            // If there is a controller also implies the user is a monkey.
13487            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
13488        }
13489    }
13490
13491    /**
13492     * @deprecated This method is only used by a few internal components and it will soon be
13493     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13494     * No new code should be calling it.
13495     */
13496    @Deprecated
13497    @Override
13498    public void requestBugReport(int bugreportType) {
13499        String extraOptions = null;
13500        switch (bugreportType) {
13501            case ActivityManager.BUGREPORT_OPTION_FULL:
13502                // Default options.
13503                break;
13504            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
13505                extraOptions = "bugreportplus";
13506                break;
13507            case ActivityManager.BUGREPORT_OPTION_REMOTE:
13508                extraOptions = "bugreportremote";
13509                break;
13510            case ActivityManager.BUGREPORT_OPTION_WEAR:
13511                extraOptions = "bugreportwear";
13512                break;
13513            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
13514                extraOptions = "bugreporttelephony";
13515                break;
13516            case ActivityManager.BUGREPORT_OPTION_WIFI:
13517                extraOptions = "bugreportwifi";
13518                break;
13519            default:
13520                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
13521                        + bugreportType);
13522        }
13523        // Always log caller, even if it does not have permission to dump.
13524        String type = extraOptions == null ? "bugreport" : extraOptions;
13525        Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
13526
13527        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13528        if (extraOptions != null) {
13529            SystemProperties.set("dumpstate.options", extraOptions);
13530        }
13531        SystemProperties.set("ctl.start", "bugreport");
13532    }
13533
13534    /**
13535     * @deprecated This method is only used by a few internal components and it will soon be
13536     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13537     * No new code should be calling it.
13538     */
13539    @Deprecated
13540    private void requestBugReportWithDescription(String shareTitle, String shareDescription,
13541                                                 int bugreportType) {
13542        if (!TextUtils.isEmpty(shareTitle)) {
13543            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13544                String errorStr = "shareTitle should be less than " +
13545                        MAX_BUGREPORT_TITLE_SIZE + " characters";
13546                throw new IllegalArgumentException(errorStr);
13547            } else {
13548                if (!TextUtils.isEmpty(shareDescription)) {
13549                    int length;
13550                    try {
13551                        length = shareDescription.getBytes("UTF-8").length;
13552                    } catch (UnsupportedEncodingException e) {
13553                        String errorStr = "shareDescription: UnsupportedEncodingException";
13554                        throw new IllegalArgumentException(errorStr);
13555                    }
13556                    if (length > SystemProperties.PROP_VALUE_MAX) {
13557                        String errorStr = "shareTitle should be less than " +
13558                                SystemProperties.PROP_VALUE_MAX + " bytes";
13559                        throw new IllegalArgumentException(errorStr);
13560                    } else {
13561                        SystemProperties.set("dumpstate.options.description", shareDescription);
13562                    }
13563                }
13564                SystemProperties.set("dumpstate.options.title", shareTitle);
13565            }
13566        }
13567
13568        Slog.d(TAG, "Bugreport notification title " + shareTitle
13569                + " description " + shareDescription);
13570        requestBugReport(bugreportType);
13571    }
13572
13573    /**
13574     * @deprecated This method is only used by a few internal components and it will soon be
13575     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13576     * No new code should be calling it.
13577     */
13578    @Deprecated
13579    @Override
13580    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13581        requestBugReportWithDescription(shareTitle, shareDescription,
13582                ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13583    }
13584
13585    /**
13586     * @deprecated This method is only used by a few internal components and it will soon be
13587     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13588     * No new code should be calling it.
13589     */
13590    @Deprecated
13591    @Override
13592    public void requestWifiBugReport(String shareTitle, String shareDescription) {
13593        requestBugReportWithDescription(shareTitle, shareDescription,
13594                ActivityManager.BUGREPORT_OPTION_WIFI);
13595    }
13596
13597
13598    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13599        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13600    }
13601
13602    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13603        if (r != null && (r.instr != null || r.usingWrapper)) {
13604            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13605        }
13606        return KEY_DISPATCHING_TIMEOUT;
13607    }
13608
13609    @Override
13610    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13611        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13612                != PackageManager.PERMISSION_GRANTED) {
13613            throw new SecurityException("Requires permission "
13614                    + android.Manifest.permission.FILTER_EVENTS);
13615        }
13616        ProcessRecord proc;
13617        long timeout;
13618        synchronized (this) {
13619            synchronized (mPidsSelfLocked) {
13620                proc = mPidsSelfLocked.get(pid);
13621            }
13622            timeout = getInputDispatchingTimeoutLocked(proc);
13623        }
13624
13625        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13626            return -1;
13627        }
13628
13629        return timeout;
13630    }
13631
13632    /**
13633     * Handle input dispatching timeouts.
13634     * Returns whether input dispatching should be aborted or not.
13635     */
13636    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13637            final ActivityRecord activity, final ActivityRecord parent,
13638            final boolean aboveSystem, String reason) {
13639        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13640                != PackageManager.PERMISSION_GRANTED) {
13641            throw new SecurityException("Requires permission "
13642                    + android.Manifest.permission.FILTER_EVENTS);
13643        }
13644
13645        final String annotation;
13646        if (reason == null) {
13647            annotation = "Input dispatching timed out";
13648        } else {
13649            annotation = "Input dispatching timed out (" + reason + ")";
13650        }
13651
13652        if (proc != null) {
13653            synchronized (this) {
13654                if (proc.debugging) {
13655                    return false;
13656                }
13657
13658                if (proc.instr != null) {
13659                    Bundle info = new Bundle();
13660                    info.putString("shortMsg", "keyDispatchingTimedOut");
13661                    info.putString("longMsg", annotation);
13662                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13663                    return true;
13664                }
13665            }
13666            mHandler.post(new Runnable() {
13667                @Override
13668                public void run() {
13669                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13670                }
13671            });
13672        }
13673
13674        return true;
13675    }
13676
13677    @Override
13678    public Bundle getAssistContextExtras(int requestType) {
13679        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13680                null, null, true /* focused */, true /* newSessionId */,
13681                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13682        if (pae == null) {
13683            return null;
13684        }
13685        synchronized (pae) {
13686            while (!pae.haveResult) {
13687                try {
13688                    pae.wait();
13689                } catch (InterruptedException e) {
13690                }
13691            }
13692        }
13693        synchronized (this) {
13694            buildAssistBundleLocked(pae, pae.result);
13695            mPendingAssistExtras.remove(pae);
13696            mUiHandler.removeCallbacks(pae);
13697        }
13698        return pae.extras;
13699    }
13700
13701    @Override
13702    public boolean isAssistDataAllowedOnCurrentActivity() {
13703        int userId;
13704        synchronized (this) {
13705            final ActivityStack focusedStack = getFocusedStack();
13706            if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
13707                return false;
13708            }
13709
13710            final ActivityRecord activity = focusedStack.getTopActivity();
13711            if (activity == null) {
13712                return false;
13713            }
13714            userId = activity.userId;
13715        }
13716        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13717                Context.DEVICE_POLICY_SERVICE);
13718        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13719    }
13720
13721    @Override
13722    public boolean showAssistFromActivity(IBinder token, Bundle args) {
13723        long ident = Binder.clearCallingIdentity();
13724        try {
13725            synchronized (this) {
13726                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13727                ActivityRecord top = getFocusedStack().getTopActivity();
13728                if (top != caller) {
13729                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13730                            + " is not current top " + top);
13731                    return false;
13732                }
13733                if (!top.nowVisible) {
13734                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13735                            + " is not visible");
13736                    return false;
13737                }
13738            }
13739            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13740                    token);
13741        } finally {
13742            Binder.restoreCallingIdentity(ident);
13743        }
13744    }
13745
13746    @Override
13747    public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
13748            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13749        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13750                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13751                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13752    }
13753
13754    @Override
13755    public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
13756            IBinder activityToken, int flags) {
13757        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13758                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13759                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13760    }
13761
13762    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13763            IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13764            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13765            int flags) {
13766        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13767                "enqueueAssistContext()");
13768
13769        synchronized (this) {
13770            ActivityRecord activity = getFocusedStack().getTopActivity();
13771            if (activity == null) {
13772                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13773                return null;
13774            }
13775            if (activity.app == null || activity.app.thread == null) {
13776                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13777                return null;
13778            }
13779            if (focused) {
13780                if (activityToken != null) {
13781                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13782                    if (activity != caller) {
13783                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13784                                + " is not current top " + activity);
13785                        return null;
13786                    }
13787                }
13788            } else {
13789                activity = ActivityRecord.forTokenLocked(activityToken);
13790                if (activity == null) {
13791                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13792                            + " couldn't be found");
13793                    return null;
13794                }
13795                if (activity.app == null || activity.app.thread == null) {
13796                    Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13797                    return null;
13798                }
13799            }
13800
13801            PendingAssistExtras pae;
13802            Bundle extras = new Bundle();
13803            if (args != null) {
13804                extras.putAll(args);
13805            }
13806            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13807            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13808
13809            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13810                    userHandle);
13811            pae.isHome = activity.isActivityTypeHome();
13812
13813            // Increment the sessionId if necessary
13814            if (newSessionId) {
13815                mViSessionId++;
13816            }
13817            try {
13818                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13819                        mViSessionId, flags);
13820                mPendingAssistExtras.add(pae);
13821                mUiHandler.postDelayed(pae, timeout);
13822            } catch (RemoteException e) {
13823                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13824                return null;
13825            }
13826            return pae;
13827        }
13828    }
13829
13830    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13831        IAssistDataReceiver receiver;
13832        synchronized (this) {
13833            mPendingAssistExtras.remove(pae);
13834            receiver = pae.receiver;
13835        }
13836        if (receiver != null) {
13837            // Caller wants result sent back to them.
13838            Bundle sendBundle = new Bundle();
13839            // At least return the receiver extras
13840            sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13841            try {
13842                pae.receiver.onHandleAssistData(sendBundle);
13843            } catch (RemoteException e) {
13844            }
13845        }
13846    }
13847
13848    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13849        if (result != null) {
13850            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13851        }
13852        if (pae.hint != null) {
13853            pae.extras.putBoolean(pae.hint, true);
13854        }
13855    }
13856
13857    /** Called from an app when assist data is ready. */
13858    @Override
13859    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13860            AssistContent content, Uri referrer) {
13861        PendingAssistExtras pae = (PendingAssistExtras)token;
13862        synchronized (pae) {
13863            pae.result = extras;
13864            pae.structure = structure;
13865            pae.content = content;
13866            if (referrer != null) {
13867                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13868            }
13869            if (structure != null) {
13870                structure.setHomeActivity(pae.isHome);
13871            }
13872            pae.haveResult = true;
13873            pae.notifyAll();
13874            if (pae.intent == null && pae.receiver == null) {
13875                // Caller is just waiting for the result.
13876                return;
13877            }
13878        }
13879        // We are now ready to launch the assist activity.
13880        IAssistDataReceiver sendReceiver = null;
13881        Bundle sendBundle = null;
13882        synchronized (this) {
13883            buildAssistBundleLocked(pae, extras);
13884            boolean exists = mPendingAssistExtras.remove(pae);
13885            mUiHandler.removeCallbacks(pae);
13886            if (!exists) {
13887                // Timed out.
13888                return;
13889            }
13890
13891            if ((sendReceiver=pae.receiver) != null) {
13892                // Caller wants result sent back to them.
13893                sendBundle = new Bundle();
13894                sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
13895                sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
13896                sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
13897                sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
13898            }
13899        }
13900        if (sendReceiver != null) {
13901            try {
13902                sendReceiver.onHandleAssistData(sendBundle);
13903            } catch (RemoteException e) {
13904            }
13905            return;
13906        }
13907
13908        final long ident = Binder.clearCallingIdentity();
13909        try {
13910            if (TextUtils.equals(pae.intent.getAction(),
13911                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13912                pae.intent.putExtras(pae.extras);
13913                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13914            } else {
13915                pae.intent.replaceExtras(pae.extras);
13916                pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
13917                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
13918                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13919                closeSystemDialogs("assist");
13920
13921                try {
13922                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13923                } catch (ActivityNotFoundException e) {
13924                    Slog.w(TAG, "No activity to handle assist action.", e);
13925                }
13926            }
13927        } finally {
13928            Binder.restoreCallingIdentity(ident);
13929        }
13930    }
13931
13932    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13933            Bundle args) {
13934        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13935                true /* focused */, true /* newSessionId */, userHandle, args,
13936                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13937    }
13938
13939    public void registerProcessObserver(IProcessObserver observer) {
13940        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13941                "registerProcessObserver()");
13942        synchronized (this) {
13943            mProcessObservers.register(observer);
13944        }
13945    }
13946
13947    @Override
13948    public void unregisterProcessObserver(IProcessObserver observer) {
13949        synchronized (this) {
13950            mProcessObservers.unregister(observer);
13951        }
13952    }
13953
13954    @Override
13955    public int getUidProcessState(int uid, String callingPackage) {
13956        if (!hasUsageStatsPermission(callingPackage)) {
13957            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13958                    "getUidProcessState");
13959        }
13960
13961        synchronized (this) {
13962            UidRecord uidRec = mActiveUids.get(uid);
13963            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13964        }
13965    }
13966
13967    @Override
13968    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13969            String callingPackage) {
13970        if (!hasUsageStatsPermission(callingPackage)) {
13971            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13972                    "registerUidObserver");
13973        }
13974        synchronized (this) {
13975            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13976                    callingPackage, which, cutpoint));
13977        }
13978    }
13979
13980    @Override
13981    public void unregisterUidObserver(IUidObserver observer) {
13982        synchronized (this) {
13983            mUidObservers.unregister(observer);
13984        }
13985    }
13986
13987    @Override
13988    public boolean convertFromTranslucent(IBinder token) {
13989        final long origId = Binder.clearCallingIdentity();
13990        try {
13991            synchronized (this) {
13992                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13993                if (r == null) {
13994                    return false;
13995                }
13996                final boolean translucentChanged = r.changeWindowTranslucency(true);
13997                if (translucentChanged) {
13998                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13999                }
14000                mWindowManager.setAppFullscreen(token, true);
14001                return translucentChanged;
14002            }
14003        } finally {
14004            Binder.restoreCallingIdentity(origId);
14005        }
14006    }
14007
14008    @Override
14009    public boolean convertToTranslucent(IBinder token, Bundle options) {
14010        SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
14011        final long origId = Binder.clearCallingIdentity();
14012        try {
14013            synchronized (this) {
14014                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14015                if (r == null) {
14016                    return false;
14017                }
14018                final TaskRecord task = r.getTask();
14019                int index = task.mActivities.lastIndexOf(r);
14020                if (index > 0) {
14021                    ActivityRecord under = task.mActivities.get(index - 1);
14022                    under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
14023                }
14024                final boolean translucentChanged = r.changeWindowTranslucency(false);
14025                if (translucentChanged) {
14026                    r.getStack().convertActivityToTranslucent(r);
14027                }
14028                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
14029                mWindowManager.setAppFullscreen(token, false);
14030                return translucentChanged;
14031            }
14032        } finally {
14033            Binder.restoreCallingIdentity(origId);
14034        }
14035    }
14036
14037    @Override
14038    public Bundle getActivityOptions(IBinder token) {
14039        final long origId = Binder.clearCallingIdentity();
14040        try {
14041            synchronized (this) {
14042                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14043                if (r != null) {
14044                    final ActivityOptions activityOptions = r.takeOptionsLocked();
14045                    return activityOptions == null ? null : activityOptions.toBundle();
14046                }
14047                return null;
14048            }
14049        } finally {
14050            Binder.restoreCallingIdentity(origId);
14051        }
14052    }
14053
14054    @Override
14055    public void setImmersive(IBinder token, boolean immersive) {
14056        synchronized(this) {
14057            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
14058            if (r == null) {
14059                throw new IllegalArgumentException();
14060            }
14061            r.immersive = immersive;
14062
14063            // update associated state if we're frontmost
14064            if (r == mStackSupervisor.getResumedActivityLocked()) {
14065                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
14066                applyUpdateLockStateLocked(r);
14067            }
14068        }
14069    }
14070
14071    @Override
14072    public boolean isImmersive(IBinder token) {
14073        synchronized (this) {
14074            ActivityRecord r = ActivityRecord.isInStackLocked(token);
14075            if (r == null) {
14076                throw new IllegalArgumentException();
14077            }
14078            return r.immersive;
14079        }
14080    }
14081
14082    @Override
14083    public void setVrThread(int tid) {
14084        enforceSystemHasVrFeature();
14085        synchronized (this) {
14086            synchronized (mPidsSelfLocked) {
14087                final int pid = Binder.getCallingPid();
14088                final ProcessRecord proc = mPidsSelfLocked.get(pid);
14089                mVrController.setVrThreadLocked(tid, pid, proc);
14090            }
14091        }
14092    }
14093
14094    @Override
14095    public void setPersistentVrThread(int tid) {
14096        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
14097            final String msg = "Permission Denial: setPersistentVrThread() from pid="
14098                    + Binder.getCallingPid()
14099                    + ", uid=" + Binder.getCallingUid()
14100                    + " requires " + permission.RESTRICTED_VR_ACCESS;
14101            Slog.w(TAG, msg);
14102            throw new SecurityException(msg);
14103        }
14104        enforceSystemHasVrFeature();
14105        synchronized (this) {
14106            synchronized (mPidsSelfLocked) {
14107                final int pid = Binder.getCallingPid();
14108                final ProcessRecord proc = mPidsSelfLocked.get(pid);
14109                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
14110            }
14111        }
14112    }
14113
14114    /**
14115     * Schedule the given thread a normal scheduling priority.
14116     *
14117     * @param tid the tid of the thread to adjust the scheduling of.
14118     * @param suppressLogs {@code true} if any error logging should be disabled.
14119     *
14120     * @return {@code true} if this succeeded.
14121     */
14122    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
14123        try {
14124            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
14125            return true;
14126        } catch (IllegalArgumentException e) {
14127            if (!suppressLogs) {
14128                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14129            }
14130        } catch (SecurityException e) {
14131            if (!suppressLogs) {
14132                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14133            }
14134        }
14135        return false;
14136    }
14137
14138    /**
14139     * Schedule the given thread an FIFO scheduling priority.
14140     *
14141     * @param tid the tid of the thread to adjust the scheduling of.
14142     * @param suppressLogs {@code true} if any error logging should be disabled.
14143     *
14144     * @return {@code true} if this succeeded.
14145     */
14146    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
14147        try {
14148            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
14149            return true;
14150        } catch (IllegalArgumentException e) {
14151            if (!suppressLogs) {
14152                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
14153            }
14154        } catch (SecurityException e) {
14155            if (!suppressLogs) {
14156                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
14157            }
14158        }
14159        return false;
14160    }
14161
14162    /**
14163     * Check that we have the features required for VR-related API calls, and throw an exception if
14164     * not.
14165     */
14166    private void enforceSystemHasVrFeature() {
14167        if (!mContext.getPackageManager().hasSystemFeature(
14168                PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
14169            throw new UnsupportedOperationException("VR mode not supported on this device!");
14170        }
14171    }
14172
14173    @Override
14174    public void setRenderThread(int tid) {
14175        synchronized (this) {
14176            ProcessRecord proc;
14177            int pid = Binder.getCallingPid();
14178            if (pid == Process.myPid()) {
14179                demoteSystemServerRenderThread(tid);
14180                return;
14181            }
14182            synchronized (mPidsSelfLocked) {
14183                proc = mPidsSelfLocked.get(pid);
14184                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
14185                    // ensure the tid belongs to the process
14186                    if (!isThreadInProcess(pid, tid)) {
14187                        throw new IllegalArgumentException(
14188                            "Render thread does not belong to process");
14189                    }
14190                    proc.renderThreadTid = tid;
14191                    if (DEBUG_OOM_ADJ) {
14192                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
14193                    }
14194                    // promote to FIFO now
14195                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
14196                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
14197                        if (mUseFifoUiScheduling) {
14198                            setThreadScheduler(proc.renderThreadTid,
14199                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
14200                        } else {
14201                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
14202                        }
14203                    }
14204                } else {
14205                    if (DEBUG_OOM_ADJ) {
14206                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
14207                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
14208                               mUseFifoUiScheduling);
14209                    }
14210                }
14211            }
14212        }
14213    }
14214
14215    /**
14216     * We only use RenderThread in system_server to store task snapshots to the disk, which should
14217     * happen in the background. Thus, demote render thread from system_server to a lower priority.
14218     *
14219     * @param tid the tid of the RenderThread
14220     */
14221    private void demoteSystemServerRenderThread(int tid) {
14222        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
14223    }
14224
14225    @Override
14226    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
14227        enforceSystemHasVrFeature();
14228
14229        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14230
14231        ActivityRecord r;
14232        synchronized (this) {
14233            r = ActivityRecord.isInStackLocked(token);
14234        }
14235
14236        if (r == null) {
14237            throw new IllegalArgumentException();
14238        }
14239
14240        int err;
14241        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
14242                VrManagerInternal.NO_ERROR) {
14243            return err;
14244        }
14245
14246        synchronized(this) {
14247            r.requestedVrComponent = (enabled) ? packageName : null;
14248
14249            // Update associated state if this activity is currently focused
14250            if (r == mStackSupervisor.getResumedActivityLocked()) {
14251                applyUpdateVrModeLocked(r);
14252            }
14253            return 0;
14254        }
14255    }
14256
14257    @Override
14258    public boolean isVrModePackageEnabled(ComponentName packageName) {
14259        enforceSystemHasVrFeature();
14260
14261        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
14262
14263        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
14264                VrManagerInternal.NO_ERROR;
14265    }
14266
14267    public boolean isTopActivityImmersive() {
14268        enforceNotIsolatedCaller("startActivity");
14269        synchronized (this) {
14270            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
14271            return (r != null) ? r.immersive : false;
14272        }
14273    }
14274
14275    /**
14276     * @return whether the system should disable UI modes incompatible with VR mode.
14277     */
14278    boolean shouldDisableNonVrUiLocked() {
14279        return mVrController.shouldDisableNonVrUiLocked();
14280    }
14281
14282    @Override
14283    public boolean isTopOfTask(IBinder token) {
14284        synchronized (this) {
14285            ActivityRecord r = ActivityRecord.isInStackLocked(token);
14286            if (r == null) {
14287                throw new IllegalArgumentException();
14288            }
14289            return r.getTask().getTopActivity() == r;
14290        }
14291    }
14292
14293    @Override
14294    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
14295        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
14296            String msg = "Permission Denial: setHasTopUi() from pid="
14297                    + Binder.getCallingPid()
14298                    + ", uid=" + Binder.getCallingUid()
14299                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
14300            Slog.w(TAG, msg);
14301            throw new SecurityException(msg);
14302        }
14303        final int pid = Binder.getCallingPid();
14304        final long origId = Binder.clearCallingIdentity();
14305        try {
14306            synchronized (this) {
14307                boolean changed = false;
14308                ProcessRecord pr;
14309                synchronized (mPidsSelfLocked) {
14310                    pr = mPidsSelfLocked.get(pid);
14311                    if (pr == null) {
14312                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
14313                        return;
14314                    }
14315                    if (pr.hasTopUi != hasTopUi) {
14316                        if (DEBUG_OOM_ADJ) {
14317                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
14318                        }
14319                        pr.hasTopUi = hasTopUi;
14320                        changed = true;
14321                    }
14322                }
14323                if (changed) {
14324                    updateOomAdjLocked(pr, true);
14325                }
14326            }
14327        } finally {
14328            Binder.restoreCallingIdentity(origId);
14329        }
14330    }
14331
14332    void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
14333        synchronized (ActivityManagerService.this) {
14334            final ProcessRecord pr;
14335            synchronized (mPidsSelfLocked) {
14336                pr = mPidsSelfLocked.get(pid);
14337                if (pr == null) {
14338                    Slog.w(TAG, "setRunningRemoteAnimation called on unknown pid: " + pid);
14339                    return;
14340                }
14341            }
14342            if (pr.runningRemoteAnimation == runningRemoteAnimation) {
14343                return;
14344            }
14345            pr.runningRemoteAnimation = runningRemoteAnimation;
14346            if (DEBUG_OOM_ADJ) {
14347                Slog.i(TAG, "Setting runningRemoteAnimation=" + pr.runningRemoteAnimation
14348                        + " for pid=" + pid);
14349            }
14350            updateOomAdjLocked(pr, true);
14351        }
14352    }
14353
14354    public final void enterSafeMode() {
14355        synchronized(this) {
14356            // It only makes sense to do this before the system is ready
14357            // and started launching other packages.
14358            if (!mSystemReady) {
14359                try {
14360                    AppGlobals.getPackageManager().enterSafeMode();
14361                } catch (RemoteException e) {
14362                }
14363            }
14364
14365            mSafeMode = true;
14366        }
14367    }
14368
14369    public final void showSafeModeOverlay() {
14370        View v = LayoutInflater.from(mContext).inflate(
14371                com.android.internal.R.layout.safe_mode, null);
14372        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
14373        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
14374        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
14375        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
14376        lp.gravity = Gravity.BOTTOM | Gravity.START;
14377        lp.format = v.getBackground().getOpacity();
14378        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
14379                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
14380        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
14381        ((WindowManager)mContext.getSystemService(
14382                Context.WINDOW_SERVICE)).addView(v, lp);
14383    }
14384
14385    @Override
14386    public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid,
14387            String sourcePkg, String tag) {
14388        if (workSource != null && workSource.isEmpty()) {
14389            workSource = null;
14390        }
14391
14392        if (sourceUid <= 0 && workSource == null) {
14393            // Try and derive a UID to attribute things to based on the caller.
14394            if (sender != null) {
14395                if (!(sender instanceof PendingIntentRecord)) {
14396                    return;
14397                }
14398
14399                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14400                final int callerUid = Binder.getCallingUid();
14401                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14402            } else {
14403                // TODO(narayan): Should we throw an exception in this case ? It means that we
14404                // haven't been able to derive a UID to attribute things to.
14405                return;
14406            }
14407        }
14408
14409        if (DEBUG_POWER) {
14410            Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid
14411                    + ", workSource=" + workSource + ", tag=" + tag + "]");
14412        }
14413
14414        mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag);
14415    }
14416
14417    @Override
14418    public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid,
14419            String tag) {
14420        if (workSource != null && workSource.isEmpty()) {
14421            workSource = null;
14422        }
14423
14424        if (sourceUid <= 0 && workSource == null) {
14425            // Try and derive a UID to attribute things to based on the caller.
14426            if (sender != null) {
14427                if (!(sender instanceof PendingIntentRecord)) {
14428                    return;
14429                }
14430
14431                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14432                final int callerUid = Binder.getCallingUid();
14433                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14434            } else {
14435                // TODO(narayan): Should we throw an exception in this case ? It means that we
14436                // haven't been able to derive a UID to attribute things to.
14437                return;
14438            }
14439        }
14440
14441        if (DEBUG_POWER) {
14442            Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource +
14443                    ", tag=" + tag + "]");
14444        }
14445
14446        mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid);
14447    }
14448
14449    @Override
14450    public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid,
14451            String tag) {
14452        if (workSource != null && workSource.isEmpty()) {
14453            workSource = null;
14454        }
14455
14456        if (sourceUid <= 0 && workSource == null) {
14457            // Try and derive a UID to attribute things to based on the caller.
14458            if (sender != null) {
14459                if (!(sender instanceof PendingIntentRecord)) {
14460                    return;
14461                }
14462
14463                final PendingIntentRecord rec = (PendingIntentRecord) sender;
14464                final int callerUid = Binder.getCallingUid();
14465                sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid;
14466            } else {
14467                // TODO(narayan): Should we throw an exception in this case ? It means that we
14468                // haven't been able to derive a UID to attribute things to.
14469                return;
14470            }
14471        }
14472
14473        if (DEBUG_POWER) {
14474            Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource +
14475                    ", tag=" + tag + "]");
14476        }
14477
14478        mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid);
14479    }
14480
14481    public boolean killPids(int[] pids, String pReason, boolean secure) {
14482        if (Binder.getCallingUid() != SYSTEM_UID) {
14483            throw new SecurityException("killPids only available to the system");
14484        }
14485        String reason = (pReason == null) ? "Unknown" : pReason;
14486        // XXX Note: don't acquire main activity lock here, because the window
14487        // manager calls in with its locks held.
14488
14489        boolean killed = false;
14490        synchronized (mPidsSelfLocked) {
14491            int worstType = 0;
14492            for (int i=0; i<pids.length; i++) {
14493                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14494                if (proc != null) {
14495                    int type = proc.setAdj;
14496                    if (type > worstType) {
14497                        worstType = type;
14498                    }
14499                }
14500            }
14501
14502            // If the worst oom_adj is somewhere in the cached proc LRU range,
14503            // then constrain it so we will kill all cached procs.
14504            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
14505                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
14506                worstType = ProcessList.CACHED_APP_MIN_ADJ;
14507            }
14508
14509            // If this is not a secure call, don't let it kill processes that
14510            // are important.
14511            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
14512                worstType = ProcessList.SERVICE_ADJ;
14513            }
14514
14515            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
14516            for (int i=0; i<pids.length; i++) {
14517                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
14518                if (proc == null) {
14519                    continue;
14520                }
14521                int adj = proc.setAdj;
14522                if (adj >= worstType && !proc.killedByAm) {
14523                    proc.kill(reason, true);
14524                    killed = true;
14525                }
14526            }
14527        }
14528        return killed;
14529    }
14530
14531    @Override
14532    public void killUid(int appId, int userId, String reason) {
14533        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
14534        synchronized (this) {
14535            final long identity = Binder.clearCallingIdentity();
14536            try {
14537                killPackageProcessesLocked(null, appId, userId,
14538                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
14539                        reason != null ? reason : "kill uid");
14540            } finally {
14541                Binder.restoreCallingIdentity(identity);
14542            }
14543        }
14544    }
14545
14546    @Override
14547    public boolean killProcessesBelowForeground(String reason) {
14548        if (Binder.getCallingUid() != SYSTEM_UID) {
14549            throw new SecurityException("killProcessesBelowForeground() only available to system");
14550        }
14551
14552        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
14553    }
14554
14555    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
14556        if (Binder.getCallingUid() != SYSTEM_UID) {
14557            throw new SecurityException("killProcessesBelowAdj() only available to system");
14558        }
14559
14560        boolean killed = false;
14561        synchronized (mPidsSelfLocked) {
14562            final int size = mPidsSelfLocked.size();
14563            for (int i = 0; i < size; i++) {
14564                final int pid = mPidsSelfLocked.keyAt(i);
14565                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14566                if (proc == null) continue;
14567
14568                final int adj = proc.setAdj;
14569                if (adj > belowAdj && !proc.killedByAm) {
14570                    proc.kill(reason, true);
14571                    killed = true;
14572                }
14573            }
14574        }
14575        return killed;
14576    }
14577
14578    @Override
14579    public void hang(final IBinder who, boolean allowRestart) {
14580        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14581                != PackageManager.PERMISSION_GRANTED) {
14582            throw new SecurityException("Requires permission "
14583                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14584        }
14585
14586        final IBinder.DeathRecipient death = new DeathRecipient() {
14587            @Override
14588            public void binderDied() {
14589                synchronized (this) {
14590                    notifyAll();
14591                }
14592            }
14593        };
14594
14595        try {
14596            who.linkToDeath(death, 0);
14597        } catch (RemoteException e) {
14598            Slog.w(TAG, "hang: given caller IBinder is already dead.");
14599            return;
14600        }
14601
14602        synchronized (this) {
14603            Watchdog.getInstance().setAllowRestart(allowRestart);
14604            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
14605            synchronized (death) {
14606                while (who.isBinderAlive()) {
14607                    try {
14608                        death.wait();
14609                    } catch (InterruptedException e) {
14610                    }
14611                }
14612            }
14613            Watchdog.getInstance().setAllowRestart(true);
14614        }
14615    }
14616
14617    @Override
14618    public void restart() {
14619        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14620                != PackageManager.PERMISSION_GRANTED) {
14621            throw new SecurityException("Requires permission "
14622                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14623        }
14624
14625        Log.i(TAG, "Sending shutdown broadcast...");
14626
14627        BroadcastReceiver br = new BroadcastReceiver() {
14628            @Override public void onReceive(Context context, Intent intent) {
14629                // Now the broadcast is done, finish up the low-level shutdown.
14630                Log.i(TAG, "Shutting down activity manager...");
14631                shutdown(10000);
14632                Log.i(TAG, "Shutdown complete, restarting!");
14633                killProcess(myPid());
14634                System.exit(10);
14635            }
14636        };
14637
14638        // First send the high-level shut down broadcast.
14639        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14640        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14641        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
14642        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
14643        mContext.sendOrderedBroadcastAsUser(intent,
14644                UserHandle.ALL, null, br, mHandler, 0, null, null);
14645        */
14646        br.onReceive(mContext, intent);
14647    }
14648
14649    private long getLowRamTimeSinceIdle(long now) {
14650        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
14651    }
14652
14653    @Override
14654    public void performIdleMaintenance() {
14655        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14656                != PackageManager.PERMISSION_GRANTED) {
14657            throw new SecurityException("Requires permission "
14658                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14659        }
14660
14661        synchronized (this) {
14662            final long now = SystemClock.uptimeMillis();
14663            final long timeSinceLastIdle = now - mLastIdleTime;
14664            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
14665            mLastIdleTime = now;
14666            mLowRamTimeSinceLastIdle = 0;
14667            if (mLowRamStartTime != 0) {
14668                mLowRamStartTime = now;
14669            }
14670
14671            StringBuilder sb = new StringBuilder(128);
14672            sb.append("Idle maintenance over ");
14673            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14674            sb.append(" low RAM for ");
14675            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14676            Slog.i(TAG, sb.toString());
14677
14678            // If at least 1/3 of our time since the last idle period has been spent
14679            // with RAM low, then we want to kill processes.
14680            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14681
14682            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14683                ProcessRecord proc = mLruProcesses.get(i);
14684                if (proc.notCachedSinceIdle) {
14685                    if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
14686                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14687                        if (doKilling && proc.initialIdlePss != 0
14688                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14689                            sb = new StringBuilder(128);
14690                            sb.append("Kill");
14691                            sb.append(proc.processName);
14692                            sb.append(" in idle maint: pss=");
14693                            sb.append(proc.lastPss);
14694                            sb.append(", swapPss=");
14695                            sb.append(proc.lastSwapPss);
14696                            sb.append(", initialPss=");
14697                            sb.append(proc.initialIdlePss);
14698                            sb.append(", period=");
14699                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14700                            sb.append(", lowRamPeriod=");
14701                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14702                            Slog.wtfQuiet(TAG, sb.toString());
14703                            proc.kill("idle maint (pss " + proc.lastPss
14704                                    + " from " + proc.initialIdlePss + ")", true);
14705                        }
14706                    }
14707                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14708                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14709                    proc.notCachedSinceIdle = true;
14710                    proc.initialIdlePss = 0;
14711                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null,
14712                            mTestPssMode, isSleepingLocked(), now);
14713                }
14714            }
14715        }
14716    }
14717
14718    @Override
14719    public void sendIdleJobTrigger() {
14720        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14721                != PackageManager.PERMISSION_GRANTED) {
14722            throw new SecurityException("Requires permission "
14723                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14724        }
14725
14726        final long ident = Binder.clearCallingIdentity();
14727        try {
14728            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14729                    .setPackage("android")
14730                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14731            broadcastIntent(null, intent, null, null, 0, null, null, null,
14732                    OP_NONE, null, true, false, UserHandle.USER_ALL);
14733        } finally {
14734            Binder.restoreCallingIdentity(ident);
14735        }
14736    }
14737
14738    private void retrieveSettings() {
14739        final ContentResolver resolver = mContext.getContentResolver();
14740        final boolean freeformWindowManagement =
14741                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14742                        || Settings.Global.getInt(
14743                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14744
14745        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14746        final boolean supportsPictureInPicture = supportsMultiWindow &&
14747                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14748        final boolean supportsSplitScreenMultiWindow =
14749                ActivityManager.supportsSplitScreenMultiWindow(mContext);
14750        final boolean supportsMultiDisplay = mContext.getPackageManager()
14751                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14752        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14753        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14754        final boolean alwaysFinishActivities =
14755                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14756        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14757        final boolean forceResizable = Settings.Global.getInt(
14758                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14759        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14760                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14761        final boolean supportsLeanbackOnly =
14762                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14763        mHiddenApiBlacklist.registerObserver();
14764
14765        // Transfer any global setting for forcing RTL layout, into a System Property
14766        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14767
14768        final Configuration configuration = new Configuration();
14769        Settings.System.getConfiguration(resolver, configuration);
14770        if (forceRtl) {
14771            // This will take care of setting the correct layout direction flags
14772            configuration.setLayoutDirection(configuration.locale);
14773        }
14774
14775        synchronized (this) {
14776            mDebugApp = mOrigDebugApp = debugApp;
14777            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14778            mAlwaysFinishActivities = alwaysFinishActivities;
14779            mSupportsLeanbackOnly = supportsLeanbackOnly;
14780            mForceResizableActivities = forceResizable;
14781            final boolean multiWindowFormEnabled = freeformWindowManagement
14782                    || supportsSplitScreenMultiWindow
14783                    || supportsPictureInPicture
14784                    || supportsMultiDisplay;
14785            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14786                mSupportsMultiWindow = true;
14787                mSupportsFreeformWindowManagement = freeformWindowManagement;
14788                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14789                mSupportsPictureInPicture = supportsPictureInPicture;
14790                mSupportsMultiDisplay = supportsMultiDisplay;
14791            } else {
14792                mSupportsMultiWindow = false;
14793                mSupportsFreeformWindowManagement = false;
14794                mSupportsSplitScreenMultiWindow = false;
14795                mSupportsPictureInPicture = false;
14796                mSupportsMultiDisplay = false;
14797            }
14798            mWindowManager.setForceResizableTasks(mForceResizableActivities);
14799            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14800            // This happens before any activities are started, so we can change global configuration
14801            // in-place.
14802            updateConfigurationLocked(configuration, null, true);
14803            final Configuration globalConfig = getGlobalConfiguration();
14804            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14805
14806            // Load resources only after the current configuration has been set.
14807            final Resources res = mContext.getResources();
14808            mThumbnailWidth = res.getDimensionPixelSize(
14809                    com.android.internal.R.dimen.thumbnail_width);
14810            mThumbnailHeight = res.getDimensionPixelSize(
14811                    com.android.internal.R.dimen.thumbnail_height);
14812            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14813                    com.android.internal.R.string.config_appsNotReportingCrashes));
14814            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14815                    com.android.internal.R.bool.config_customUserSwitchUi);
14816            mUserController.mMaxRunningUsers = res.getInteger(
14817                    com.android.internal.R.integer.config_multiuserMaxRunningUsers);
14818
14819            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14820                mFullscreenThumbnailScale = (float) res
14821                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14822                    (float) globalConfig.screenWidthDp;
14823            } else {
14824                mFullscreenThumbnailScale = res.getFraction(
14825                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14826            }
14827            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14828        }
14829    }
14830
14831    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14832        traceLog.traceBegin("PhaseActivityManagerReady");
14833        synchronized(this) {
14834            if (mSystemReady) {
14835                // If we're done calling all the receivers, run the next "boot phase" passed in
14836                // by the SystemServer
14837                if (goingCallback != null) {
14838                    goingCallback.run();
14839                }
14840                return;
14841            }
14842
14843            mLocalDeviceIdleController
14844                    = LocalServices.getService(DeviceIdleController.LocalService.class);
14845            mAssistUtils = new AssistUtils(mContext);
14846            mVrController.onSystemReady();
14847            // Make sure we have the current profile info, since it is needed for security checks.
14848            mUserController.onSystemReady();
14849            mRecentTasks.onSystemReadyLocked();
14850            mAppOpsService.systemReady();
14851            mSystemReady = true;
14852        }
14853
14854        try {
14855            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14856                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14857                    .getSerial();
14858        } catch (RemoteException e) {}
14859
14860        ArrayList<ProcessRecord> procsToKill = null;
14861        synchronized(mPidsSelfLocked) {
14862            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14863                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14864                if (!isAllowedWhileBooting(proc.info)){
14865                    if (procsToKill == null) {
14866                        procsToKill = new ArrayList<ProcessRecord>();
14867                    }
14868                    procsToKill.add(proc);
14869                }
14870            }
14871        }
14872
14873        synchronized(this) {
14874            if (procsToKill != null) {
14875                for (int i=procsToKill.size()-1; i>=0; i--) {
14876                    ProcessRecord proc = procsToKill.get(i);
14877                    Slog.i(TAG, "Removing system update proc: " + proc);
14878                    removeProcessLocked(proc, true, false, "system update done");
14879                }
14880            }
14881
14882            // Now that we have cleaned up any update processes, we
14883            // are ready to start launching real processes and know that
14884            // we won't trample on them any more.
14885            mProcessesReady = true;
14886        }
14887
14888        Slog.i(TAG, "System now ready");
14889        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14890            SystemClock.uptimeMillis());
14891
14892        synchronized(this) {
14893            // Make sure we have no pre-ready processes sitting around.
14894
14895            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14896                ResolveInfo ri = mContext.getPackageManager()
14897                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14898                                STOCK_PM_FLAGS);
14899                CharSequence errorMsg = null;
14900                if (ri != null) {
14901                    ActivityInfo ai = ri.activityInfo;
14902                    ApplicationInfo app = ai.applicationInfo;
14903                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14904                        mTopAction = Intent.ACTION_FACTORY_TEST;
14905                        mTopData = null;
14906                        mTopComponent = new ComponentName(app.packageName,
14907                                ai.name);
14908                    } else {
14909                        errorMsg = mContext.getResources().getText(
14910                                com.android.internal.R.string.factorytest_not_system);
14911                    }
14912                } else {
14913                    errorMsg = mContext.getResources().getText(
14914                            com.android.internal.R.string.factorytest_no_action);
14915                }
14916                if (errorMsg != null) {
14917                    mTopAction = null;
14918                    mTopData = null;
14919                    mTopComponent = null;
14920                    Message msg = Message.obtain();
14921                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14922                    msg.getData().putCharSequence("msg", errorMsg);
14923                    mUiHandler.sendMessage(msg);
14924                }
14925            }
14926        }
14927
14928        retrieveSettings();
14929        final int currentUserId = mUserController.getCurrentUserId();
14930        synchronized (this) {
14931            readGrantedUriPermissionsLocked();
14932        }
14933
14934        final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
14935        if (pmi != null) {
14936            pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
14937                    state -> updateForceBackgroundCheck(state.batterySaverEnabled));
14938            updateForceBackgroundCheck(
14939                    pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
14940        } else {
14941            Slog.wtf(TAG, "PowerManagerInternal not found.");
14942        }
14943
14944        if (goingCallback != null) goingCallback.run();
14945        traceLog.traceBegin("ActivityManagerStartApps");
14946        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14947                Integer.toString(currentUserId), currentUserId);
14948        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14949                Integer.toString(currentUserId), currentUserId);
14950        mSystemServiceManager.startUser(currentUserId);
14951
14952        synchronized (this) {
14953            // Only start up encryption-aware persistent apps; once user is
14954            // unlocked we'll come back around and start unaware apps
14955            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14956
14957            // Start up initial activity.
14958            mBooting = true;
14959            // Enable home activity for system user, so that the system can always boot. We don't
14960            // do this when the system user is not setup since the setup wizard should be the one
14961            // to handle home activity in this case.
14962            if (UserManager.isSplitSystemUser() &&
14963                    Settings.Secure.getInt(mContext.getContentResolver(),
14964                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14965                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14966                try {
14967                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14968                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14969                            UserHandle.USER_SYSTEM);
14970                } catch (RemoteException e) {
14971                    throw e.rethrowAsRuntimeException();
14972                }
14973            }
14974            startHomeActivityLocked(currentUserId, "systemReady");
14975
14976            try {
14977                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14978                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14979                            + " data partition or your device will be unstable.");
14980                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14981                }
14982            } catch (RemoteException e) {
14983            }
14984
14985            if (!Build.isBuildConsistent()) {
14986                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14987                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14988            }
14989
14990            long ident = Binder.clearCallingIdentity();
14991            try {
14992                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14993                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14994                        | Intent.FLAG_RECEIVER_FOREGROUND);
14995                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14996                broadcastIntentLocked(null, null, intent,
14997                        null, null, 0, null, null, null, OP_NONE,
14998                        null, false, false, MY_PID, SYSTEM_UID,
14999                        currentUserId);
15000                intent = new Intent(Intent.ACTION_USER_STARTING);
15001                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15002                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
15003                broadcastIntentLocked(null, null, intent,
15004                        null, new IIntentReceiver.Stub() {
15005                            @Override
15006                            public void performReceive(Intent intent, int resultCode, String data,
15007                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
15008                                    throws RemoteException {
15009                            }
15010                        }, 0, null, null,
15011                        new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
15012                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
15013            } catch (Throwable t) {
15014                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
15015            } finally {
15016                Binder.restoreCallingIdentity(ident);
15017            }
15018            mStackSupervisor.resumeFocusedStackTopActivityLocked();
15019            mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
15020
15021            BinderInternal.nSetBinderProxyCountEnabled(true);
15022            BinderInternal.setBinderProxyCountCallback(
15023                    new BinderInternal.BinderProxyLimitListener() {
15024                        @Override
15025                        public void onLimitReached(int uid) {
15026                            Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
15027                                    + Process.myUid());
15028                            if (uid == Process.SYSTEM_UID) {
15029                                Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
15030                            } else {
15031                                killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
15032                                        "Too many Binders sent to SYSTEM");
15033                            }
15034                        }
15035                    }, mHandler);
15036
15037            traceLog.traceEnd(); // ActivityManagerStartApps
15038            traceLog.traceEnd(); // PhaseActivityManagerReady
15039        }
15040    }
15041
15042    private void updateForceBackgroundCheck(boolean enabled) {
15043        synchronized (this) {
15044            if (mForceBackgroundCheck != enabled) {
15045                mForceBackgroundCheck = enabled;
15046
15047                if (DEBUG_BACKGROUND_CHECK) {
15048                    Slog.i(TAG, "Force background check " + (enabled ? "enabled" : "disabled"));
15049                }
15050
15051                if (mForceBackgroundCheck) {
15052                    // Stop background services for idle UIDs.
15053                    doStopUidForIdleUidsLocked();
15054                }
15055            }
15056        }
15057    }
15058
15059    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
15060        synchronized (this) {
15061            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
15062        }
15063    }
15064
15065    void skipCurrentReceiverLocked(ProcessRecord app) {
15066        for (BroadcastQueue queue : mBroadcastQueues) {
15067            queue.skipCurrentReceiverLocked(app);
15068        }
15069    }
15070
15071    /**
15072     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
15073     * The application process will exit immediately after this call returns.
15074     * @param app object of the crashing app, null for the system server
15075     * @param crashInfo describing the exception
15076     */
15077    public void handleApplicationCrash(IBinder app,
15078            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15079        ProcessRecord r = findAppProcess(app, "Crash");
15080        final String processName = app == null ? "system_server"
15081                : (r == null ? "unknown" : r.processName);
15082
15083        handleApplicationCrashInner("crash", r, processName, crashInfo);
15084    }
15085
15086    /* Native crash reporting uses this inner version because it needs to be somewhat
15087     * decoupled from the AM-managed cleanup lifecycle
15088     */
15089    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
15090            ApplicationErrorReport.CrashInfo crashInfo) {
15091        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
15092                UserHandle.getUserId(Binder.getCallingUid()), processName,
15093                r == null ? -1 : r.info.flags,
15094                crashInfo.exceptionClassName,
15095                crashInfo.exceptionMessage,
15096                crashInfo.throwFileName,
15097                crashInfo.throwLineNumber);
15098
15099        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
15100
15101        mAppErrors.crashApplication(r, crashInfo);
15102    }
15103
15104    public void handleApplicationStrictModeViolation(
15105            IBinder app,
15106            int violationMask,
15107            StrictMode.ViolationInfo info) {
15108        // We're okay if the ProcessRecord is missing; it probably means that
15109        // we're reporting a violation from the system process itself.
15110        final ProcessRecord r = findAppProcess(app, "StrictMode");
15111
15112        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
15113            Integer stackFingerprint = info.hashCode();
15114            boolean logIt = true;
15115            synchronized (mAlreadyLoggedViolatedStacks) {
15116                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
15117                    logIt = false;
15118                    // TODO: sub-sample into EventLog for these, with
15119                    // the info.durationMillis?  Then we'd get
15120                    // the relative pain numbers, without logging all
15121                    // the stack traces repeatedly.  We'd want to do
15122                    // likewise in the client code, which also does
15123                    // dup suppression, before the Binder call.
15124                } else {
15125                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
15126                        mAlreadyLoggedViolatedStacks.clear();
15127                    }
15128                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
15129                }
15130            }
15131            if (logIt) {
15132                logStrictModeViolationToDropBox(r, info);
15133            }
15134        }
15135
15136        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
15137            AppErrorResult result = new AppErrorResult();
15138            synchronized (this) {
15139                final long origId = Binder.clearCallingIdentity();
15140
15141                Message msg = Message.obtain();
15142                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
15143                HashMap<String, Object> data = new HashMap<String, Object>();
15144                data.put("result", result);
15145                data.put("app", r);
15146                data.put("violationMask", violationMask);
15147                data.put("info", info);
15148                msg.obj = data;
15149                mUiHandler.sendMessage(msg);
15150
15151                Binder.restoreCallingIdentity(origId);
15152            }
15153            int res = result.get();
15154            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
15155        }
15156    }
15157
15158    // Depending on the policy in effect, there could be a bunch of
15159    // these in quick succession so we try to batch these together to
15160    // minimize disk writes, number of dropbox entries, and maximize
15161    // compression, by having more fewer, larger records.
15162    private void logStrictModeViolationToDropBox(
15163            ProcessRecord process,
15164            StrictMode.ViolationInfo info) {
15165        if (info == null) {
15166            return;
15167        }
15168        final boolean isSystemApp = process == null ||
15169                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
15170                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
15171        final String processName = process == null ? "unknown" : process.processName;
15172        final DropBoxManager dbox = (DropBoxManager)
15173                mContext.getSystemService(Context.DROPBOX_SERVICE);
15174
15175        // Exit early if the dropbox isn't configured to accept this report type.
15176        final String dropboxTag = processClass(process) + "_strictmode";
15177        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15178
15179        final StringBuilder sb = new StringBuilder(1024);
15180        synchronized (sb) {
15181            appendDropBoxProcessHeaders(process, processName, sb);
15182            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15183            sb.append("System-App: ").append(isSystemApp).append("\n");
15184            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
15185            if (info.violationNumThisLoop != 0) {
15186                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
15187            }
15188            if (info.numAnimationsRunning != 0) {
15189                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
15190            }
15191            if (info.broadcastIntentAction != null) {
15192                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
15193            }
15194            if (info.durationMillis != -1) {
15195                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
15196            }
15197            if (info.numInstances != -1) {
15198                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
15199            }
15200            if (info.tags != null) {
15201                for (String tag : info.tags) {
15202                    sb.append("Span-Tag: ").append(tag).append("\n");
15203                }
15204            }
15205            sb.append("\n");
15206            sb.append(info.getStackTrace());
15207            sb.append("\n");
15208            if (info.getViolationDetails() != null) {
15209                sb.append(info.getViolationDetails());
15210                sb.append("\n");
15211            }
15212        }
15213
15214        final String res = sb.toString();
15215        IoThread.getHandler().post(() -> {
15216            dbox.addText(dropboxTag, res);
15217        });
15218    }
15219
15220    /**
15221     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
15222     * @param app object of the crashing app, null for the system server
15223     * @param tag reported by the caller
15224     * @param system whether this wtf is coming from the system
15225     * @param crashInfo describing the context of the error
15226     * @return true if the process should exit immediately (WTF is fatal)
15227     */
15228    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
15229            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
15230        final int callingUid = Binder.getCallingUid();
15231        final int callingPid = Binder.getCallingPid();
15232
15233        if (system) {
15234            // If this is coming from the system, we could very well have low-level
15235            // system locks held, so we want to do this all asynchronously.  And we
15236            // never want this to become fatal, so there is that too.
15237            mHandler.post(new Runnable() {
15238                @Override public void run() {
15239                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
15240                }
15241            });
15242            return false;
15243        }
15244
15245        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
15246                crashInfo);
15247
15248        final boolean isFatal = Build.IS_ENG || Settings.Global
15249                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
15250        final boolean isSystem = (r == null) || r.persistent;
15251
15252        if (isFatal && !isSystem) {
15253            mAppErrors.crashApplication(r, crashInfo);
15254            return true;
15255        } else {
15256            return false;
15257        }
15258    }
15259
15260    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
15261            final ApplicationErrorReport.CrashInfo crashInfo) {
15262        final ProcessRecord r = findAppProcess(app, "WTF");
15263        final String processName = app == null ? "system_server"
15264                : (r == null ? "unknown" : r.processName);
15265
15266        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
15267                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
15268
15269        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
15270
15271        return r;
15272    }
15273
15274    /**
15275     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
15276     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
15277     */
15278    private ProcessRecord findAppProcess(IBinder app, String reason) {
15279        if (app == null) {
15280            return null;
15281        }
15282
15283        synchronized (this) {
15284            final int NP = mProcessNames.getMap().size();
15285            for (int ip=0; ip<NP; ip++) {
15286                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
15287                final int NA = apps.size();
15288                for (int ia=0; ia<NA; ia++) {
15289                    ProcessRecord p = apps.valueAt(ia);
15290                    if (p.thread != null && p.thread.asBinder() == app) {
15291                        return p;
15292                    }
15293                }
15294            }
15295
15296            Slog.w(TAG, "Can't find mystery application for " + reason
15297                    + " from pid=" + Binder.getCallingPid()
15298                    + " uid=" + Binder.getCallingUid() + ": " + app);
15299            return null;
15300        }
15301    }
15302
15303    /**
15304     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
15305     * to append various headers to the dropbox log text.
15306     */
15307    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
15308            StringBuilder sb) {
15309        // Watchdog thread ends up invoking this function (with
15310        // a null ProcessRecord) to add the stack file to dropbox.
15311        // Do not acquire a lock on this (am) in such cases, as it
15312        // could cause a potential deadlock, if and when watchdog
15313        // is invoked due to unavailability of lock on am and it
15314        // would prevent watchdog from killing system_server.
15315        if (process == null) {
15316            sb.append("Process: ").append(processName).append("\n");
15317            return;
15318        }
15319        // Note: ProcessRecord 'process' is guarded by the service
15320        // instance.  (notably process.pkgList, which could otherwise change
15321        // concurrently during execution of this method)
15322        synchronized (this) {
15323            sb.append("Process: ").append(processName).append("\n");
15324            sb.append("PID: ").append(process.pid).append("\n");
15325            int flags = process.info.flags;
15326            IPackageManager pm = AppGlobals.getPackageManager();
15327            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
15328            for (int ip=0; ip<process.pkgList.size(); ip++) {
15329                String pkg = process.pkgList.keyAt(ip);
15330                sb.append("Package: ").append(pkg);
15331                try {
15332                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
15333                    if (pi != null) {
15334                        sb.append(" v").append(pi.getLongVersionCode());
15335                        if (pi.versionName != null) {
15336                            sb.append(" (").append(pi.versionName).append(")");
15337                        }
15338                    }
15339                } catch (RemoteException e) {
15340                    Slog.e(TAG, "Error getting package info: " + pkg, e);
15341                }
15342                sb.append("\n");
15343            }
15344            if (process.info.isInstantApp()) {
15345                sb.append("Instant-App: true\n");
15346            }
15347        }
15348    }
15349
15350    private static String processClass(ProcessRecord process) {
15351        if (process == null || process.pid == MY_PID) {
15352            return "system_server";
15353        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15354            return "system_app";
15355        } else {
15356            return "data_app";
15357        }
15358    }
15359
15360    private volatile long mWtfClusterStart;
15361    private volatile int mWtfClusterCount;
15362
15363    /**
15364     * Write a description of an error (crash, WTF, ANR) to the drop box.
15365     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
15366     * @param process which caused the error, null means the system server
15367     * @param activity which triggered the error, null if unknown
15368     * @param parent activity related to the error, null if unknown
15369     * @param subject line related to the error, null if absent
15370     * @param report in long form describing the error, null if absent
15371     * @param dataFile text file to include in the report, null if none
15372     * @param crashInfo giving an application stack trace, null if absent
15373     */
15374    public void addErrorToDropBox(String eventType,
15375            ProcessRecord process, String processName, ActivityRecord activity,
15376            ActivityRecord parent, String subject,
15377            final String report, final File dataFile,
15378            final ApplicationErrorReport.CrashInfo crashInfo) {
15379        // NOTE -- this must never acquire the ActivityManagerService lock,
15380        // otherwise the watchdog may be prevented from resetting the system.
15381
15382        // Bail early if not published yet
15383        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
15384        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
15385
15386        // Exit early if the dropbox isn't configured to accept this report type.
15387        final String dropboxTag = processClass(process) + "_" + eventType;
15388        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
15389
15390        // Log to StatsLog before the rate-limiting.
15391        // The logging below is adapated from appendDropboxProcessHeaders.
15392        StatsLog.write(StatsLog.DROPBOX_ERROR_CHANGED,
15393                process != null ? process.uid : -1,
15394                dropboxTag,
15395                processName,
15396                process != null ? process.pid : -1,
15397                (process != null && process.info != null) ?
15398                        (process.info.isInstantApp() ? 1 : 0) : -1,
15399                activity != null ? activity.shortComponentName : null,
15400                activity != null ? activity.packageName : null,
15401                process != null ? (process.isInterestingToUserLocked() ? 1 : 0) : -1);
15402
15403        // Rate-limit how often we're willing to do the heavy lifting below to
15404        // collect and record logs; currently 5 logs per 10 second period.
15405        final long now = SystemClock.elapsedRealtime();
15406        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
15407            mWtfClusterStart = now;
15408            mWtfClusterCount = 1;
15409        } else {
15410            if (mWtfClusterCount++ >= 5) return;
15411        }
15412
15413        final StringBuilder sb = new StringBuilder(1024);
15414        appendDropBoxProcessHeaders(process, processName, sb);
15415        if (process != null) {
15416            sb.append("Foreground: ")
15417                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
15418                    .append("\n");
15419        }
15420        if (activity != null) {
15421            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
15422        }
15423        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
15424            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
15425        }
15426        if (parent != null && parent != activity) {
15427            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
15428        }
15429        if (subject != null) {
15430            sb.append("Subject: ").append(subject).append("\n");
15431        }
15432        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
15433        if (Debug.isDebuggerConnected()) {
15434            sb.append("Debugger: Connected\n");
15435        }
15436        sb.append("\n");
15437
15438        // Do the rest in a worker thread to avoid blocking the caller on I/O
15439        // (After this point, we shouldn't access AMS internal data structures.)
15440        Thread worker = new Thread("Error dump: " + dropboxTag) {
15441            @Override
15442            public void run() {
15443                if (report != null) {
15444                    sb.append(report);
15445                }
15446
15447                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
15448                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
15449                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
15450                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
15451
15452                if (dataFile != null && maxDataFileSize > 0) {
15453                    try {
15454                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
15455                                    "\n\n[[TRUNCATED]]"));
15456                    } catch (IOException e) {
15457                        Slog.e(TAG, "Error reading " + dataFile, e);
15458                    }
15459                }
15460                if (crashInfo != null && crashInfo.stackTrace != null) {
15461                    sb.append(crashInfo.stackTrace);
15462                }
15463
15464                if (lines > 0) {
15465                    sb.append("\n");
15466
15467                    // Merge several logcat streams, and take the last N lines
15468                    InputStreamReader input = null;
15469                    try {
15470                        java.lang.Process logcat = new ProcessBuilder(
15471                                "/system/bin/timeout", "-k", "15s", "10s",
15472                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
15473                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
15474                                        .redirectErrorStream(true).start();
15475
15476                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
15477                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
15478                        input = new InputStreamReader(logcat.getInputStream());
15479
15480                        int num;
15481                        char[] buf = new char[8192];
15482                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
15483                    } catch (IOException e) {
15484                        Slog.e(TAG, "Error running logcat", e);
15485                    } finally {
15486                        if (input != null) try { input.close(); } catch (IOException e) {}
15487                    }
15488                }
15489
15490                dbox.addText(dropboxTag, sb.toString());
15491            }
15492        };
15493
15494        if (process == null) {
15495            // If process is null, we are being called from some internal code
15496            // and may be about to die -- run this synchronously.
15497            final int oldMask = StrictMode.allowThreadDiskWritesMask();
15498            try {
15499                worker.run();
15500            } finally {
15501                StrictMode.setThreadPolicyMask(oldMask);
15502            }
15503        } else {
15504            worker.start();
15505        }
15506    }
15507
15508    @Override
15509    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
15510        enforceNotIsolatedCaller("getProcessesInErrorState");
15511        // assume our apps are happy - lazy create the list
15512        List<ActivityManager.ProcessErrorStateInfo> errList = null;
15513
15514        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15515                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
15516        int userId = UserHandle.getUserId(Binder.getCallingUid());
15517
15518        synchronized (this) {
15519
15520            // iterate across all processes
15521            for (int i=mLruProcesses.size()-1; i>=0; i--) {
15522                ProcessRecord app = mLruProcesses.get(i);
15523                if (!allUsers && app.userId != userId) {
15524                    continue;
15525                }
15526                if ((app.thread != null) && (app.crashing || app.notResponding)) {
15527                    // This one's in trouble, so we'll generate a report for it
15528                    // crashes are higher priority (in case there's a crash *and* an anr)
15529                    ActivityManager.ProcessErrorStateInfo report = null;
15530                    if (app.crashing) {
15531                        report = app.crashingReport;
15532                    } else if (app.notResponding) {
15533                        report = app.notRespondingReport;
15534                    }
15535
15536                    if (report != null) {
15537                        if (errList == null) {
15538                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
15539                        }
15540                        errList.add(report);
15541                    } else {
15542                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
15543                                " crashing = " + app.crashing +
15544                                " notResponding = " + app.notResponding);
15545                    }
15546                }
15547            }
15548        }
15549
15550        return errList;
15551    }
15552
15553    static int procStateToImportance(int procState, int memAdj,
15554            ActivityManager.RunningAppProcessInfo currApp,
15555            int clientTargetSdk) {
15556        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
15557                procState, clientTargetSdk);
15558        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
15559            currApp.lru = memAdj;
15560        } else {
15561            currApp.lru = 0;
15562        }
15563        return imp;
15564    }
15565
15566    private void fillInProcMemInfo(ProcessRecord app,
15567            ActivityManager.RunningAppProcessInfo outInfo,
15568            int clientTargetSdk) {
15569        outInfo.pid = app.pid;
15570        outInfo.uid = app.info.uid;
15571        if (mHeavyWeightProcess == app) {
15572            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
15573        }
15574        if (app.persistent) {
15575            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
15576        }
15577        if (app.activities.size() > 0) {
15578            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
15579        }
15580        outInfo.lastTrimLevel = app.trimMemoryLevel;
15581        int adj = app.curAdj;
15582        int procState = app.curProcState;
15583        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
15584        outInfo.importanceReasonCode = app.adjTypeCode;
15585        outInfo.processState = app.curProcState;
15586    }
15587
15588    @Override
15589    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
15590        enforceNotIsolatedCaller("getRunningAppProcesses");
15591
15592        final int callingUid = Binder.getCallingUid();
15593        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15594
15595        // Lazy instantiation of list
15596        List<ActivityManager.RunningAppProcessInfo> runList = null;
15597        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
15598                callingUid) == PackageManager.PERMISSION_GRANTED;
15599        final int userId = UserHandle.getUserId(callingUid);
15600        final boolean allUids = isGetTasksAllowed(
15601                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
15602
15603        synchronized (this) {
15604            // Iterate across all processes
15605            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15606                ProcessRecord app = mLruProcesses.get(i);
15607                if ((!allUsers && app.userId != userId)
15608                        || (!allUids && app.uid != callingUid)) {
15609                    continue;
15610                }
15611                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
15612                    // Generate process state info for running application
15613                    ActivityManager.RunningAppProcessInfo currApp =
15614                        new ActivityManager.RunningAppProcessInfo(app.processName,
15615                                app.pid, app.getPackageList());
15616                    fillInProcMemInfo(app, currApp, clientTargetSdk);
15617                    if (app.adjSource instanceof ProcessRecord) {
15618                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
15619                        currApp.importanceReasonImportance =
15620                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
15621                                        app.adjSourceProcState);
15622                    } else if (app.adjSource instanceof ActivityRecord) {
15623                        ActivityRecord r = (ActivityRecord)app.adjSource;
15624                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
15625                    }
15626                    if (app.adjTarget instanceof ComponentName) {
15627                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
15628                    }
15629                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
15630                    //        + " lru=" + currApp.lru);
15631                    if (runList == null) {
15632                        runList = new ArrayList<>();
15633                    }
15634                    runList.add(currApp);
15635                }
15636            }
15637        }
15638        return runList;
15639    }
15640
15641    @Override
15642    public List<ApplicationInfo> getRunningExternalApplications() {
15643        enforceNotIsolatedCaller("getRunningExternalApplications");
15644        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
15645        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
15646        if (runningApps != null && runningApps.size() > 0) {
15647            Set<String> extList = new HashSet<String>();
15648            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
15649                if (app.pkgList != null) {
15650                    for (String pkg : app.pkgList) {
15651                        extList.add(pkg);
15652                    }
15653                }
15654            }
15655            IPackageManager pm = AppGlobals.getPackageManager();
15656            for (String pkg : extList) {
15657                try {
15658                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
15659                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
15660                        retList.add(info);
15661                    }
15662                } catch (RemoteException e) {
15663                }
15664            }
15665        }
15666        return retList;
15667    }
15668
15669    @Override
15670    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15671        enforceNotIsolatedCaller("getMyMemoryState");
15672
15673        final int callingUid = Binder.getCallingUid();
15674        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15675
15676        synchronized (this) {
15677            ProcessRecord proc;
15678            synchronized (mPidsSelfLocked) {
15679                proc = mPidsSelfLocked.get(Binder.getCallingPid());
15680            }
15681            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15682        }
15683    }
15684
15685    @Override
15686    public int getMemoryTrimLevel() {
15687        enforceNotIsolatedCaller("getMyMemoryState");
15688        synchronized (this) {
15689            return mLastMemoryLevel;
15690        }
15691    }
15692
15693    @Override
15694    public void onShellCommand(FileDescriptor in, FileDescriptor out,
15695            FileDescriptor err, String[] args, ShellCallback callback,
15696            ResultReceiver resultReceiver) {
15697        (new ActivityManagerShellCommand(this, false)).exec(
15698                this, in, out, err, args, callback, resultReceiver);
15699    }
15700
15701    SleepToken acquireSleepToken(String tag, int displayId) {
15702        synchronized (this) {
15703            final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15704            updateSleepIfNeededLocked();
15705            return token;
15706        }
15707    }
15708
15709    @Override
15710    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15711        PriorityDump.dump(mPriorityDumper, fd, pw, args);
15712    }
15713
15714    /**
15715     * Wrapper function to print out debug data filtered by specified arguments.
15716    */
15717    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
15718        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15719
15720        boolean dumpAll = false;
15721        boolean dumpClient = false;
15722        boolean dumpCheckin = false;
15723        boolean dumpCheckinFormat = false;
15724        boolean dumpNormalPriority = false;
15725        boolean dumpVisibleStacksOnly = false;
15726        boolean dumpFocusedStackOnly = false;
15727        String dumpPackage = null;
15728
15729        int opti = 0;
15730        while (opti < args.length) {
15731            String opt = args[opti];
15732            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15733                break;
15734            }
15735            opti++;
15736            if ("-a".equals(opt)) {
15737                dumpAll = true;
15738            } else if ("-c".equals(opt)) {
15739                dumpClient = true;
15740            } else if ("-v".equals(opt)) {
15741                dumpVisibleStacksOnly = true;
15742            } else if ("-f".equals(opt)) {
15743                dumpFocusedStackOnly = true;
15744            } else if ("-p".equals(opt)) {
15745                if (opti < args.length) {
15746                    dumpPackage = args[opti];
15747                    opti++;
15748                } else {
15749                    pw.println("Error: -p option requires package argument");
15750                    return;
15751                }
15752                dumpClient = true;
15753            } else if ("--checkin".equals(opt)) {
15754                dumpCheckin = dumpCheckinFormat = true;
15755            } else if ("-C".equals(opt)) {
15756                dumpCheckinFormat = true;
15757            } else if ("--normal-priority".equals(opt)) {
15758                dumpNormalPriority = true;
15759            } else if ("-h".equals(opt)) {
15760                ActivityManagerShellCommand.dumpHelp(pw, true);
15761                return;
15762            } else {
15763                pw.println("Unknown argument: " + opt + "; use -h for help");
15764            }
15765        }
15766
15767        long origId = Binder.clearCallingIdentity();
15768
15769        if (useProto) {
15770            final ProtoOutputStream proto = new ProtoOutputStream(fd);
15771            String cmd = opti < args.length ? args[opti] : "";
15772            opti++;
15773
15774            if ("activities".equals(cmd) || "a".equals(cmd)) {
15775                // output proto is ActivityStackSupervisorProto
15776                synchronized (this) {
15777                    writeActivitiesToProtoLocked(proto);
15778                }
15779            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15780                // output proto is BroadcastProto
15781                synchronized (this) {
15782                    writeBroadcastsToProtoLocked(proto);
15783                }
15784            } else if ("provider".equals(cmd)) {
15785                String[] newArgs;
15786                String name;
15787                if (opti >= args.length) {
15788                    name = null;
15789                    newArgs = EMPTY_STRING_ARRAY;
15790                } else {
15791                    name = args[opti];
15792                    opti++;
15793                    newArgs = new String[args.length - opti];
15794                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15795                            args.length - opti);
15796                }
15797                if (!dumpProviderProto(fd, pw, name, newArgs)) {
15798                    pw.println("No providers match: " + name);
15799                    pw.println("Use -h for help.");
15800                }
15801            } else if ("service".equals(cmd)) {
15802                mServices.writeToProto(proto);
15803            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15804                if (opti < args.length) {
15805                    dumpPackage = args[opti];
15806                    opti++;
15807                }
15808                // output proto is ProcessProto
15809                synchronized (this) {
15810                    writeProcessesToProtoLocked(proto, dumpPackage);
15811                }
15812            } else {
15813                // default option, dump everything, output is ActivityManagerServiceProto
15814                synchronized (this) {
15815                    long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
15816                    writeActivitiesToProtoLocked(proto);
15817                    proto.end(activityToken);
15818
15819                    long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
15820                    writeBroadcastsToProtoLocked(proto);
15821                    proto.end(broadcastToken);
15822
15823                    long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
15824                    mServices.writeToProto(proto);
15825                    proto.end(serviceToken);
15826
15827                    long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
15828                    writeProcessesToProtoLocked(proto, dumpPackage);
15829                    proto.end(processToken);
15830                }
15831            }
15832            proto.flush();
15833            Binder.restoreCallingIdentity(origId);
15834            return;
15835        }
15836
15837        int dumpAppId = getAppId(dumpPackage);
15838        boolean more = false;
15839        // Is the caller requesting to dump a particular piece of data?
15840        if (opti < args.length) {
15841            String cmd = args[opti];
15842            opti++;
15843            if ("activities".equals(cmd) || "a".equals(cmd)) {
15844                synchronized (this) {
15845                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15846                }
15847            } else if ("lastanr".equals(cmd)) {
15848                synchronized (this) {
15849                    dumpLastANRLocked(pw);
15850                }
15851            } else if ("starter".equals(cmd)) {
15852                synchronized (this) {
15853                    dumpActivityStarterLocked(pw, dumpPackage);
15854                }
15855            } else if ("containers".equals(cmd)) {
15856                synchronized (this) {
15857                    dumpActivityContainersLocked(pw);
15858                }
15859            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15860                synchronized (this) {
15861                    if (mRecentTasks != null) {
15862                        mRecentTasks.dump(pw, true /* dumpAll */, dumpPackage);
15863                    }
15864                }
15865            } else if ("binder-proxies".equals(cmd)) {
15866                if (opti >= args.length) {
15867                    dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
15868                            "Counts of Binder Proxies held by SYSTEM");
15869                } else {
15870                    String uid = args[opti];
15871                    opti++;
15872                    // Ensure Binder Proxy Count is as up to date as possible
15873                    System.gc();
15874                    System.runFinalization();
15875                    System.gc();
15876                    pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
15877                }
15878            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15879                if (opti < args.length) {
15880                    dumpPackage = args[opti];
15881                    opti++;
15882                }
15883                synchronized (this) {
15884                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15885                }
15886            } else if ("broadcast-stats".equals(cmd)) {
15887                if (opti < args.length) {
15888                    dumpPackage = args[opti];
15889                    opti++;
15890                }
15891                synchronized (this) {
15892                    if (dumpCheckinFormat) {
15893                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15894                                dumpPackage);
15895                    } else {
15896                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15897                    }
15898                }
15899            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15900                if (opti < args.length) {
15901                    dumpPackage = args[opti];
15902                    opti++;
15903                }
15904                synchronized (this) {
15905                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15906                }
15907            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15908                if (opti < args.length) {
15909                    dumpPackage = args[opti];
15910                    opti++;
15911                }
15912                synchronized (this) {
15913                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
15914                }
15915            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15916                synchronized (this) {
15917                    dumpOomLocked(fd, pw, args, opti, true);
15918                }
15919            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15920                synchronized (this) {
15921                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
15922                }
15923            } else if ("provider".equals(cmd)) {
15924                String[] newArgs;
15925                String name;
15926                if (opti >= args.length) {
15927                    name = null;
15928                    newArgs = EMPTY_STRING_ARRAY;
15929                } else {
15930                    name = args[opti];
15931                    opti++;
15932                    newArgs = new String[args.length - opti];
15933                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15934                }
15935                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15936                    pw.println("No providers match: " + name);
15937                    pw.println("Use -h for help.");
15938                }
15939            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15940                synchronized (this) {
15941                    dumpProvidersLocked(fd, pw, args, opti, true, null);
15942                }
15943            } else if ("service".equals(cmd)) {
15944                String[] newArgs;
15945                String name;
15946                if (opti >= args.length) {
15947                    name = null;
15948                    newArgs = EMPTY_STRING_ARRAY;
15949                } else {
15950                    name = args[opti];
15951                    opti++;
15952                    newArgs = new String[args.length - opti];
15953                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15954                            args.length - opti);
15955                }
15956                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15957                    pw.println("No services match: " + name);
15958                    pw.println("Use -h for help.");
15959                }
15960            } else if ("package".equals(cmd)) {
15961                String[] newArgs;
15962                if (opti >= args.length) {
15963                    pw.println("package: no package name specified");
15964                    pw.println("Use -h for help.");
15965                } else {
15966                    dumpPackage = args[opti];
15967                    opti++;
15968                    newArgs = new String[args.length - opti];
15969                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15970                            args.length - opti);
15971                    args = newArgs;
15972                    opti = 0;
15973                    more = true;
15974                }
15975            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15976                synchronized (this) {
15977                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15978                }
15979            } else if ("settings".equals(cmd)) {
15980                synchronized (this) {
15981                    mConstants.dump(pw);
15982                }
15983            } else if ("services".equals(cmd) || "s".equals(cmd)) {
15984                if (dumpClient) {
15985                    ActiveServices.ServiceDumper dumper;
15986                    synchronized (this) {
15987                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15988                                dumpPackage);
15989                    }
15990                    dumper.dumpWithClient();
15991                } else {
15992                    synchronized (this) {
15993                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15994                                dumpPackage).dumpLocked();
15995                    }
15996                }
15997            } else if ("locks".equals(cmd)) {
15998                LockGuard.dump(fd, pw, args);
15999            } else {
16000                // Dumping a single activity?
16001                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
16002                        dumpFocusedStackOnly)) {
16003                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
16004                    int res = shell.exec(this, null, fd, null, args, null,
16005                            new ResultReceiver(null));
16006                    if (res < 0) {
16007                        pw.println("Bad activity command, or no activities match: " + cmd);
16008                        pw.println("Use -h for help.");
16009                    }
16010                }
16011            }
16012            if (!more) {
16013                Binder.restoreCallingIdentity(origId);
16014                return;
16015            }
16016        }
16017
16018        // No piece of data specified, dump everything.
16019        if (dumpCheckinFormat) {
16020            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
16021        } else if (dumpClient) {
16022            ActiveServices.ServiceDumper sdumper;
16023            synchronized (this) {
16024                mConstants.dump(pw);
16025                pw.println();
16026                if (dumpAll) {
16027                    pw.println("-------------------------------------------------------------------------------");
16028                }
16029                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16030                pw.println();
16031                if (dumpAll) {
16032                    pw.println("-------------------------------------------------------------------------------");
16033                }
16034                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16035                pw.println();
16036                if (dumpAll) {
16037                    pw.println("-------------------------------------------------------------------------------");
16038                }
16039                if (dumpAll || dumpPackage != null) {
16040                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16041                    pw.println();
16042                    if (dumpAll) {
16043                        pw.println("-------------------------------------------------------------------------------");
16044                    }
16045                }
16046                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16047                pw.println();
16048                if (dumpAll) {
16049                    pw.println("-------------------------------------------------------------------------------");
16050                }
16051                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16052                pw.println();
16053                if (dumpAll) {
16054                    pw.println("-------------------------------------------------------------------------------");
16055                }
16056                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
16057                        dumpPackage);
16058            }
16059            sdumper.dumpWithClient();
16060            pw.println();
16061            synchronized (this) {
16062                if (dumpAll) {
16063                    pw.println("-------------------------------------------------------------------------------");
16064                }
16065                if (mRecentTasks != null) {
16066                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
16067                }
16068                pw.println();
16069                if (dumpAll) {
16070                    pw.println("-------------------------------------------------------------------------------");
16071                }
16072                dumpLastANRLocked(pw);
16073                pw.println();
16074                if (dumpAll) {
16075                    pw.println("-------------------------------------------------------------------------------");
16076                }
16077                dumpActivityStarterLocked(pw, dumpPackage);
16078                pw.println();
16079                if (dumpAll) {
16080                    pw.println("-------------------------------------------------------------------------------");
16081                }
16082                dumpActivityContainersLocked(pw);
16083                pw.println();
16084                if (dumpAll) {
16085                    pw.println("-------------------------------------------------------------------------------");
16086                }
16087                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16088                if (mAssociations.size() > 0) {
16089                    pw.println();
16090                    if (dumpAll) {
16091                        pw.println("-------------------------------------------------------------------------------");
16092                    }
16093                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16094                }
16095                pw.println();
16096                if (dumpAll) {
16097                    pw.println("-------------------------------------------------------------------------------");
16098                }
16099                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16100            }
16101
16102        } else {
16103            synchronized (this) {
16104                mConstants.dump(pw);
16105                pw.println();
16106                if (dumpAll) {
16107                    pw.println("-------------------------------------------------------------------------------");
16108                }
16109                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16110                pw.println();
16111                if (dumpAll) {
16112                    pw.println("-------------------------------------------------------------------------------");
16113                }
16114                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16115                pw.println();
16116                if (dumpAll) {
16117                    pw.println("-------------------------------------------------------------------------------");
16118                }
16119                if (dumpAll || dumpPackage != null) {
16120                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16121                    pw.println();
16122                    if (dumpAll) {
16123                        pw.println("-------------------------------------------------------------------------------");
16124                    }
16125                }
16126                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16127                pw.println();
16128                if (dumpAll) {
16129                    pw.println("-------------------------------------------------------------------------------");
16130                }
16131                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
16132                pw.println();
16133                if (dumpAll) {
16134                    pw.println("-------------------------------------------------------------------------------");
16135                }
16136                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
16137                        .dumpLocked();
16138                pw.println();
16139                if (dumpAll) {
16140                    pw.println("-------------------------------------------------------------------------------");
16141                }
16142                if (mRecentTasks != null) {
16143                    mRecentTasks.dump(pw, dumpAll, dumpPackage);
16144                }
16145                pw.println();
16146                if (dumpAll) {
16147                    pw.println("-------------------------------------------------------------------------------");
16148                }
16149                dumpLastANRLocked(pw);
16150                pw.println();
16151                if (dumpAll) {
16152                    pw.println("-------------------------------------------------------------------------------");
16153                }
16154                dumpActivityStarterLocked(pw, dumpPackage);
16155                pw.println();
16156                if (dumpAll) {
16157                    pw.println("-------------------------------------------------------------------------------");
16158                }
16159                dumpActivityContainersLocked(pw);
16160                // Activities section is dumped as part of the Critical priority dump. Exclude the
16161                // section if priority is Normal.
16162                if (!dumpNormalPriority){
16163                    pw.println();
16164                    if (dumpAll) {
16165                        pw.println("-------------------------------------------------------------------------------");
16166                    }
16167                    dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16168                }
16169                if (mAssociations.size() > 0) {
16170                    pw.println();
16171                    if (dumpAll) {
16172                        pw.println("-------------------------------------------------------------------------------");
16173                    }
16174                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
16175                }
16176                pw.println();
16177                if (dumpAll) {
16178                    pw.println("-------------------------------------------------------------------------------");
16179                }
16180                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId);
16181            }
16182        }
16183        Binder.restoreCallingIdentity(origId);
16184    }
16185
16186    private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
16187        // The output proto of "activity --proto activities" is ActivityStackSupervisorProto
16188        mStackSupervisor.writeToProto(proto);
16189    }
16190
16191    private void dumpLastANRLocked(PrintWriter pw) {
16192        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
16193        if (mLastANRState == null) {
16194            pw.println("  <no ANR has occurred since boot>");
16195        } else {
16196            pw.println(mLastANRState);
16197        }
16198    }
16199
16200    private void dumpActivityContainersLocked(PrintWriter pw) {
16201        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
16202        mStackSupervisor.dumpChildrenNames(pw, " ");
16203        pw.println(" ");
16204    }
16205
16206    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
16207        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
16208        mActivityStartController.dump(pw, "", dumpPackage);
16209    }
16210
16211    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16212            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16213        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
16214                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
16215    }
16216
16217    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16218            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
16219        pw.println(header);
16220
16221        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
16222                dumpPackage);
16223        boolean needSep = printedAnything;
16224
16225        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
16226                mStackSupervisor.getResumedActivityLocked(),
16227                dumpPackage, needSep, "  ResumedActivity: ");
16228        if (printed) {
16229            printedAnything = true;
16230            needSep = false;
16231        }
16232
16233        if (dumpPackage == null) {
16234            if (needSep) {
16235                pw.println();
16236            }
16237            printedAnything = true;
16238            mStackSupervisor.dump(pw, "  ");
16239        }
16240
16241        if (!printedAnything) {
16242            pw.println("  (nothing)");
16243        }
16244    }
16245
16246    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16247            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
16248        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
16249
16250        int dumpUid = 0;
16251        if (dumpPackage != null) {
16252            IPackageManager pm = AppGlobals.getPackageManager();
16253            try {
16254                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
16255            } catch (RemoteException e) {
16256            }
16257        }
16258
16259        boolean printedAnything = false;
16260
16261        final long now = SystemClock.uptimeMillis();
16262
16263        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
16264            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
16265                    = mAssociations.valueAt(i1);
16266            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
16267                SparseArray<ArrayMap<String, Association>> sourceUids
16268                        = targetComponents.valueAt(i2);
16269                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
16270                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
16271                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
16272                        Association ass = sourceProcesses.valueAt(i4);
16273                        if (dumpPackage != null) {
16274                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
16275                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
16276                                continue;
16277                            }
16278                        }
16279                        printedAnything = true;
16280                        pw.print("  ");
16281                        pw.print(ass.mTargetProcess);
16282                        pw.print("/");
16283                        UserHandle.formatUid(pw, ass.mTargetUid);
16284                        pw.print(" <- ");
16285                        pw.print(ass.mSourceProcess);
16286                        pw.print("/");
16287                        UserHandle.formatUid(pw, ass.mSourceUid);
16288                        pw.println();
16289                        pw.print("    via ");
16290                        pw.print(ass.mTargetComponent.flattenToShortString());
16291                        pw.println();
16292                        pw.print("    ");
16293                        long dur = ass.mTime;
16294                        if (ass.mNesting > 0) {
16295                            dur += now - ass.mStartTime;
16296                        }
16297                        TimeUtils.formatDuration(dur, pw);
16298                        pw.print(" (");
16299                        pw.print(ass.mCount);
16300                        pw.print(" times)");
16301                        pw.print("  ");
16302                        for (int i=0; i<ass.mStateTimes.length; i++) {
16303                            long amt = ass.mStateTimes[i];
16304                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16305                                amt += now - ass.mLastStateUptime;
16306                            }
16307                            if (amt != 0) {
16308                                pw.print(" ");
16309                                pw.print(ProcessList.makeProcStateString(
16310                                            i + ActivityManager.MIN_PROCESS_STATE));
16311                                pw.print("=");
16312                                TimeUtils.formatDuration(amt, pw);
16313                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
16314                                    pw.print("*");
16315                                }
16316                            }
16317                        }
16318                        pw.println();
16319                        if (ass.mNesting > 0) {
16320                            pw.print("    Currently active: ");
16321                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
16322                            pw.println();
16323                        }
16324                    }
16325                }
16326            }
16327
16328        }
16329
16330        if (!printedAnything) {
16331            pw.println("  (nothing)");
16332        }
16333    }
16334
16335    private int getAppId(String dumpPackage) {
16336        if (dumpPackage != null) {
16337            try {
16338                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
16339                        dumpPackage, 0);
16340                return UserHandle.getAppId(info.uid);
16341            } catch (NameNotFoundException e) {
16342                e.printStackTrace();
16343            }
16344        }
16345        return -1;
16346    }
16347
16348    boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
16349                String header, boolean needSep) {
16350        boolean printed = false;
16351        for (int i=0; i<uids.size(); i++) {
16352            UidRecord uidRec = uids.valueAt(i);
16353            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != dumpAppId) {
16354                continue;
16355            }
16356            if (!printed) {
16357                printed = true;
16358                if (needSep) {
16359                    pw.println();
16360                }
16361                pw.print("  ");
16362                pw.println(header);
16363                needSep = true;
16364            }
16365            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
16366            pw.print(": "); pw.println(uidRec);
16367        }
16368        return printed;
16369    }
16370
16371    boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
16372        if(counts != null) {
16373            pw.println(header);
16374            for (int i = 0; i < counts.size(); i++) {
16375                final int uid = counts.keyAt(i);
16376                final int binderCount = counts.valueAt(i);
16377                pw.print("    UID ");
16378                pw.print(uid);
16379                pw.print(", binder count = ");
16380                pw.print(binderCount);
16381                pw.print(", package(s)= ");
16382                final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
16383                if (pkgNames != null) {
16384                    for (int j = 0; j < pkgNames.length; j++) {
16385                        pw.print(pkgNames[j]);
16386                        pw.print("; ");
16387                    }
16388                } else {
16389                    pw.print("NO PACKAGE NAME FOUND");
16390                }
16391                pw.println();
16392            }
16393            pw.println();
16394            return true;
16395        }
16396        return false;
16397    }
16398
16399    @GuardedBy("this")
16400    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16401            int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
16402        boolean needSep = false;
16403        int numPers = 0;
16404
16405        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
16406
16407        if (dumpAll) {
16408            final int NP = mProcessNames.getMap().size();
16409            for (int ip=0; ip<NP; ip++) {
16410                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16411                final int NA = procs.size();
16412                for (int ia=0; ia<NA; ia++) {
16413                    ProcessRecord r = procs.valueAt(ia);
16414                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16415                        continue;
16416                    }
16417                    if (!needSep) {
16418                        pw.println("  All known processes:");
16419                        needSep = true;
16420                    }
16421                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
16422                        pw.print(" UID "); pw.print(procs.keyAt(ia));
16423                        pw.print(" "); pw.println(r);
16424                    r.dump(pw, "    ");
16425                    if (r.persistent) {
16426                        numPers++;
16427                    }
16428                }
16429            }
16430        }
16431
16432        if (mIsolatedProcesses.size() > 0) {
16433            boolean printed = false;
16434            for (int i=0; i<mIsolatedProcesses.size(); i++) {
16435                ProcessRecord r = mIsolatedProcesses.valueAt(i);
16436                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16437                    continue;
16438                }
16439                if (!printed) {
16440                    if (needSep) {
16441                        pw.println();
16442                    }
16443                    pw.println("  Isolated process list (sorted by uid):");
16444                    printed = true;
16445                    needSep = true;
16446                }
16447                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
16448                pw.println(r);
16449            }
16450        }
16451
16452        if (mActiveInstrumentation.size() > 0) {
16453            boolean printed = false;
16454            for (int i=0; i<mActiveInstrumentation.size(); i++) {
16455                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16456                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16457                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16458                    continue;
16459                }
16460                if (!printed) {
16461                    if (needSep) {
16462                        pw.println();
16463                    }
16464                    pw.println("  Active instrumentation:");
16465                    printed = true;
16466                    needSep = true;
16467                }
16468                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
16469                pw.println(ai);
16470                ai.dump(pw, "      ");
16471            }
16472        }
16473
16474        if (mActiveUids.size() > 0) {
16475            if (dumpUids(pw, dumpPackage, dumpAppId, mActiveUids, "UID states:", needSep)) {
16476                needSep = true;
16477            }
16478        }
16479        if (dumpAll) {
16480            if (mValidateUids.size() > 0) {
16481                if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
16482                        needSep)) {
16483                    needSep = true;
16484                }
16485            }
16486        }
16487
16488        if (mLruProcesses.size() > 0) {
16489            if (needSep) {
16490                pw.println();
16491            }
16492            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
16493                    pw.print(" total, non-act at ");
16494                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16495                    pw.print(", non-svc at ");
16496                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16497                    pw.println("):");
16498            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
16499            needSep = true;
16500        }
16501
16502        if (dumpAll || dumpPackage != null) {
16503            synchronized (mPidsSelfLocked) {
16504                boolean printed = false;
16505                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16506                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16507                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16508                        continue;
16509                    }
16510                    if (!printed) {
16511                        if (needSep) pw.println();
16512                        needSep = true;
16513                        pw.println("  PID mappings:");
16514                        printed = true;
16515                    }
16516                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
16517                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
16518                }
16519            }
16520        }
16521
16522        if (mImportantProcesses.size() > 0) {
16523            synchronized (mPidsSelfLocked) {
16524                boolean printed = false;
16525                for (int i = 0; i< mImportantProcesses.size(); i++) {
16526                    ProcessRecord r = mPidsSelfLocked.get(
16527                            mImportantProcesses.valueAt(i).pid);
16528                    if (dumpPackage != null && (r == null
16529                            || !r.pkgList.containsKey(dumpPackage))) {
16530                        continue;
16531                    }
16532                    if (!printed) {
16533                        if (needSep) pw.println();
16534                        needSep = true;
16535                        pw.println("  Foreground Processes:");
16536                        printed = true;
16537                    }
16538                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
16539                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
16540                }
16541            }
16542        }
16543
16544        if (mPersistentStartingProcesses.size() > 0) {
16545            if (needSep) pw.println();
16546            needSep = true;
16547            pw.println("  Persisent processes that are starting:");
16548            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
16549                    "Starting Norm", "Restarting PERS", dumpPackage);
16550        }
16551
16552        if (mRemovedProcesses.size() > 0) {
16553            if (needSep) pw.println();
16554            needSep = true;
16555            pw.println("  Processes that are being removed:");
16556            dumpProcessList(pw, this, mRemovedProcesses, "    ",
16557                    "Removed Norm", "Removed PERS", dumpPackage);
16558        }
16559
16560        if (mProcessesOnHold.size() > 0) {
16561            if (needSep) pw.println();
16562            needSep = true;
16563            pw.println("  Processes that are on old until the system is ready:");
16564            dumpProcessList(pw, this, mProcessesOnHold, "    ",
16565                    "OnHold Norm", "OnHold PERS", dumpPackage);
16566        }
16567
16568        needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
16569
16570        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
16571
16572        if (dumpPackage == null) {
16573            pw.println();
16574            needSep = false;
16575            mUserController.dump(pw, dumpAll);
16576        }
16577        if (mHomeProcess != null && (dumpPackage == null
16578                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16579            if (needSep) {
16580                pw.println();
16581                needSep = false;
16582            }
16583            pw.println("  mHomeProcess: " + mHomeProcess);
16584        }
16585        if (mPreviousProcess != null && (dumpPackage == null
16586                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16587            if (needSep) {
16588                pw.println();
16589                needSep = false;
16590            }
16591            pw.println("  mPreviousProcess: " + mPreviousProcess);
16592        }
16593        if (dumpAll && (mPreviousProcess == null || dumpPackage == null
16594                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
16595            StringBuilder sb = new StringBuilder(128);
16596            sb.append("  mPreviousProcessVisibleTime: ");
16597            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
16598            pw.println(sb);
16599        }
16600        if (mHeavyWeightProcess != null && (dumpPackage == null
16601                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
16602            if (needSep) {
16603                pw.println();
16604                needSep = false;
16605            }
16606            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16607        }
16608        if (dumpAll && mPendingStarts.size() > 0) {
16609            if (needSep) pw.println();
16610            needSep = true;
16611            pw.println("  mPendingStarts: ");
16612            for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
16613                pw.println("    " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
16614            }
16615        }
16616        if (dumpPackage == null) {
16617            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
16618            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
16619        }
16620        if (dumpAll) {
16621            if (dumpPackage == null) {
16622                pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
16623            }
16624            if (mCompatModePackages.getPackages().size() > 0) {
16625                boolean printed = false;
16626                for (Map.Entry<String, Integer> entry
16627                        : mCompatModePackages.getPackages().entrySet()) {
16628                    String pkg = entry.getKey();
16629                    int mode = entry.getValue();
16630                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
16631                        continue;
16632                    }
16633                    if (!printed) {
16634                        pw.println("  mScreenCompatPackages:");
16635                        printed = true;
16636                    }
16637                    pw.print("    "); pw.print(pkg); pw.print(": ");
16638                            pw.print(mode); pw.println();
16639                }
16640            }
16641            final int NI = mUidObservers.getRegisteredCallbackCount();
16642            boolean printed = false;
16643            for (int i=0; i<NI; i++) {
16644                final UidObserverRegistration reg = (UidObserverRegistration)
16645                        mUidObservers.getRegisteredCallbackCookie(i);
16646                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
16647                    if (!printed) {
16648                        pw.println("  mUidObservers:");
16649                        printed = true;
16650                    }
16651                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
16652                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
16653                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
16654                        pw.print(" IDLE");
16655                    }
16656                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
16657                        pw.print(" ACT" );
16658                    }
16659                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
16660                        pw.print(" GONE");
16661                    }
16662                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
16663                        pw.print(" STATE");
16664                        pw.print(" (cut="); pw.print(reg.cutpoint);
16665                        pw.print(")");
16666                    }
16667                    pw.println();
16668                    if (reg.lastProcStates != null) {
16669                        final int NJ = reg.lastProcStates.size();
16670                        for (int j=0; j<NJ; j++) {
16671                            pw.print("      Last ");
16672                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
16673                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
16674                        }
16675                    }
16676                }
16677            }
16678            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
16679            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
16680            if (mPendingTempWhitelist.size() > 0) {
16681                pw.println("  mPendingTempWhitelist:");
16682                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
16683                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
16684                    pw.print("    ");
16685                    UserHandle.formatUid(pw, ptw.targetUid);
16686                    pw.print(": ");
16687                    TimeUtils.formatDuration(ptw.duration, pw);
16688                    pw.print(" ");
16689                    pw.println(ptw.tag);
16690                }
16691            }
16692        }
16693        if (dumpPackage == null) {
16694            pw.println("  mWakefulness="
16695                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
16696            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
16697            pw.println("  mSleeping=" + mSleeping);
16698            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
16699            if (mRunningVoice != null) {
16700                pw.println("  mRunningVoice=" + mRunningVoice);
16701                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
16702            }
16703            pw.println("  mVrController=" + mVrController);
16704        }
16705        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16706                || mOrigWaitForDebugger) {
16707            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16708                    || dumpPackage.equals(mOrigDebugApp)) {
16709                if (needSep) {
16710                    pw.println();
16711                    needSep = false;
16712                }
16713                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
16714                        + " mDebugTransient=" + mDebugTransient
16715                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
16716            }
16717        }
16718        if (mCurAppTimeTracker != null) {
16719            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
16720        }
16721        if (mMemWatchProcesses.getMap().size() > 0) {
16722            pw.println("  Mem watch processes:");
16723            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
16724                    = mMemWatchProcesses.getMap();
16725            for (int i=0; i<procs.size(); i++) {
16726                final String proc = procs.keyAt(i);
16727                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16728                for (int j=0; j<uids.size(); j++) {
16729                    if (needSep) {
16730                        pw.println();
16731                        needSep = false;
16732                    }
16733                    StringBuilder sb = new StringBuilder();
16734                    sb.append("    ").append(proc).append('/');
16735                    UserHandle.formatUid(sb, uids.keyAt(j));
16736                    Pair<Long, String> val = uids.valueAt(j);
16737                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
16738                    if (val.second != null) {
16739                        sb.append(", report to ").append(val.second);
16740                    }
16741                    pw.println(sb.toString());
16742                }
16743            }
16744            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
16745            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
16746            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
16747                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
16748        }
16749        if (mTrackAllocationApp != null) {
16750            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16751                if (needSep) {
16752                    pw.println();
16753                    needSep = false;
16754                }
16755                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
16756            }
16757        }
16758        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16759                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16760            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16761                if (needSep) {
16762                    pw.println();
16763                    needSep = false;
16764                }
16765                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16766                if (mProfilerInfo != null) {
16767                    pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16768                            mProfilerInfo.profileFd);
16769                    pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
16770                            " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16771                            " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16772                    pw.println("  mProfileType=" + mProfileType);
16773                }
16774            }
16775        }
16776        if (mNativeDebuggingApp != null) {
16777            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16778                if (needSep) {
16779                    pw.println();
16780                    needSep = false;
16781                }
16782                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16783            }
16784        }
16785        if (mAllowAppSwitchUids.size() > 0) {
16786            boolean printed = false;
16787            for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
16788                ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
16789                for (int j = 0; j < types.size(); j++) {
16790                    if (dumpPackage == null ||
16791                            UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
16792                        if (needSep) {
16793                            pw.println();
16794                            needSep = false;
16795                        }
16796                        if (!printed) {
16797                            pw.println("  mAllowAppSwitchUids:");
16798                            printed = true;
16799                        }
16800                        pw.print("    User ");
16801                        pw.print(mAllowAppSwitchUids.keyAt(i));
16802                        pw.print(": Type ");
16803                        pw.print(types.keyAt(j));
16804                        pw.print(" = ");
16805                        UserHandle.formatUid(pw, types.valueAt(j).intValue());
16806                        pw.println();
16807                    }
16808                }
16809            }
16810        }
16811        if (dumpPackage == null) {
16812            if (mAlwaysFinishActivities) {
16813                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16814            }
16815            if (mController != null) {
16816                pw.println("  mController=" + mController
16817                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16818            }
16819            if (dumpAll) {
16820                pw.println("  Total persistent processes: " + numPers);
16821                pw.println("  mProcessesReady=" + mProcessesReady
16822                        + " mSystemReady=" + mSystemReady
16823                        + " mBooted=" + mBooted
16824                        + " mFactoryTest=" + mFactoryTest);
16825                pw.println("  mBooting=" + mBooting
16826                        + " mCallFinishBooting=" + mCallFinishBooting
16827                        + " mBootAnimationComplete=" + mBootAnimationComplete);
16828                pw.print("  mLastPowerCheckUptime=");
16829                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16830                        pw.println("");
16831                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16832                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16833                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16834                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16835                        + " (" + mLruProcesses.size() + " total)"
16836                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16837                        + " mNumServiceProcs=" + mNumServiceProcs
16838                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16839                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16840                        + " mLastMemoryLevel=" + mLastMemoryLevel
16841                        + " mLastNumProcesses=" + mLastNumProcesses);
16842                long now = SystemClock.uptimeMillis();
16843                pw.print("  mLastIdleTime=");
16844                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
16845                        pw.print(" mLowRamSinceLastIdle=");
16846                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16847                        pw.println();
16848                pw.println();
16849                pw.print("  mUidChangeDispatchCount=");
16850                pw.print(mUidChangeDispatchCount);
16851                pw.println();
16852
16853                pw.println("  Slow UID dispatches:");
16854                final int N = mUidObservers.beginBroadcast();
16855                for (int i = 0; i < N; i++) {
16856                    UidObserverRegistration r =
16857                            (UidObserverRegistration) mUidObservers.getBroadcastCookie(i);
16858                    pw.print("    ");
16859                    pw.print(mUidObservers.getBroadcastItem(i).getClass().getTypeName());
16860                    pw.print(": ");
16861                    pw.print(r.mSlowDispatchCount);
16862                    pw.print(" / Max ");
16863                    pw.print(r.mMaxDispatchTime);
16864                    pw.println("ms");
16865                }
16866                mUidObservers.finishBroadcast();
16867            }
16868        }
16869        pw.println("  mForceBackgroundCheck=" + mForceBackgroundCheck);
16870    }
16871
16872    @GuardedBy("this")
16873    void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
16874        int numPers = 0;
16875
16876        final int NP = mProcessNames.getMap().size();
16877        for (int ip=0; ip<NP; ip++) {
16878            SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
16879            final int NA = procs.size();
16880            for (int ia = 0; ia<NA; ia++) {
16881                ProcessRecord r = procs.valueAt(ia);
16882                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16883                    continue;
16884                }
16885                r.writeToProto(proto, ProcessesProto.PROCS);
16886                if (r.persistent) {
16887                    numPers++;
16888                }
16889            }
16890        }
16891
16892        for (int i=0; i<mIsolatedProcesses.size(); i++) {
16893            ProcessRecord r = mIsolatedProcesses.valueAt(i);
16894            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16895                continue;
16896            }
16897            r.writeToProto(proto, ProcessesProto.ISOLATED_PROCS);
16898        }
16899
16900        for (int i=0; i<mActiveInstrumentation.size(); i++) {
16901            ActiveInstrumentation ai = mActiveInstrumentation.get(i);
16902            if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
16903                    && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
16904                continue;
16905            }
16906            ai.writeToProto(proto, ProcessesProto.ACTIVE_INSTRUMENTATIONS);
16907        }
16908
16909        int whichAppId = getAppId(dumpPackage);
16910        for (int i=0; i<mActiveUids.size(); i++) {
16911            UidRecord uidRec = mActiveUids.valueAt(i);
16912            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
16913                continue;
16914            }
16915            uidRec.writeToProto(proto, ProcessesProto.ACTIVE_UIDS);
16916        }
16917
16918        for (int i=0; i<mValidateUids.size(); i++) {
16919            UidRecord uidRec = mValidateUids.valueAt(i);
16920            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
16921                continue;
16922            }
16923            uidRec.writeToProto(proto, ProcessesProto.VALIDATE_UIDS);
16924        }
16925
16926        if (mLruProcesses.size() > 0) {
16927            long lruToken = proto.start(ProcessesProto.LRU_PROCS);
16928            int total = mLruProcesses.size();
16929            proto.write(ProcessesProto.LruProcesses.SIZE, total);
16930            proto.write(ProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
16931            proto.write(ProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
16932            writeProcessOomListToProto(proto, ProcessesProto.LruProcesses.LIST, this,
16933                    mLruProcesses,false, dumpPackage);
16934            proto.end(lruToken);
16935        }
16936
16937        if (dumpPackage != null) {
16938            synchronized (mPidsSelfLocked) {
16939                for (int i=0; i<mPidsSelfLocked.size(); i++) {
16940                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
16941                    if (!r.pkgList.containsKey(dumpPackage)) {
16942                        continue;
16943                    }
16944                    r.writeToProto(proto, ProcessesProto.PIDS_SELF_LOCKED);
16945                }
16946            }
16947        }
16948
16949        if (mImportantProcesses.size() > 0) {
16950            synchronized (mPidsSelfLocked) {
16951                for (int i=0; i<mImportantProcesses.size(); i++) {
16952                    ImportanceToken it = mImportantProcesses.valueAt(i);
16953                    ProcessRecord r = mPidsSelfLocked.get(it.pid);
16954                    if (dumpPackage != null && (r == null
16955                            || !r.pkgList.containsKey(dumpPackage))) {
16956                        continue;
16957                    }
16958                    it.writeToProto(proto, ProcessesProto.IMPORTANT_PROCS);
16959                }
16960            }
16961        }
16962
16963        for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
16964            ProcessRecord r = mPersistentStartingProcesses.get(i);
16965            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16966                continue;
16967            }
16968            r.writeToProto(proto, ProcessesProto.PERSISTENT_STARTING_PROCS);
16969        }
16970
16971        for (int i=0; i<mRemovedProcesses.size(); i++) {
16972            ProcessRecord r = mRemovedProcesses.get(i);
16973            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16974                continue;
16975            }
16976            r.writeToProto(proto, ProcessesProto.REMOVED_PROCS);
16977        }
16978
16979        for (int i=0; i<mProcessesOnHold.size(); i++) {
16980            ProcessRecord r = mProcessesOnHold.get(i);
16981            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16982                continue;
16983            }
16984            r.writeToProto(proto, ProcessesProto.ON_HOLD_PROCS);
16985        }
16986
16987        writeProcessesToGcToProto(proto, ProcessesProto.GC_PROCS, dumpPackage);
16988        mAppErrors.writeToProto(proto, ProcessesProto.APP_ERRORS, dumpPackage);
16989
16990        if (dumpPackage == null) {
16991            mUserController.writeToProto(proto, ProcessesProto.USER_CONTROLLER);
16992            getGlobalConfiguration().writeToProto(proto, ProcessesProto.GLOBAL_CONFIGURATION);
16993            proto.write(ProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
16994        }
16995
16996        if (mHomeProcess != null && (dumpPackage == null
16997                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
16998            mHomeProcess.writeToProto(proto, ProcessesProto.HOME_PROC);
16999        }
17000
17001        if (mPreviousProcess != null && (dumpPackage == null
17002                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
17003            mPreviousProcess.writeToProto(proto, ProcessesProto.PREVIOUS_PROC);
17004            proto.write(ProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
17005        }
17006
17007        if (mHeavyWeightProcess != null && (dumpPackage == null
17008                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
17009            mHeavyWeightProcess.writeToProto(proto, ProcessesProto.HEAVY_WEIGHT_PROC);
17010        }
17011
17012        for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
17013            String pkg = entry.getKey();
17014            int mode = entry.getValue();
17015            if (dumpPackage == null || dumpPackage.equals(pkg)) {
17016                long compatToken = proto.start(ProcessesProto.SCREEN_COMPAT_PACKAGES);
17017                proto.write(ProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
17018                proto.write(ProcessesProto.ScreenCompatPackage.MODE, mode);
17019                proto.end(compatToken);
17020            }
17021        }
17022
17023        final int NI = mUidObservers.getRegisteredCallbackCount();
17024        for (int i=0; i<NI; i++) {
17025            final UidObserverRegistration reg = (UidObserverRegistration)
17026                    mUidObservers.getRegisteredCallbackCookie(i);
17027            if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
17028                reg.writeToProto(proto, ProcessesProto.UID_OBSERVERS);
17029            }
17030        }
17031
17032        for (int v : mDeviceIdleWhitelist) {
17033            proto.write(ProcessesProto.DEVICE_IDLE_WHITELIST, v);
17034        }
17035
17036        for (int v : mDeviceIdleTempWhitelist) {
17037            proto.write(ProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
17038        }
17039
17040        if (mPendingTempWhitelist.size() > 0) {
17041            for (int i=0; i < mPendingTempWhitelist.size(); i++) {
17042                mPendingTempWhitelist.valueAt(i).writeToProto(proto,
17043                        ProcessesProto.PENDING_TEMP_WHITELIST);
17044            }
17045        }
17046
17047        if (dumpPackage == null) {
17048            final long sleepToken = proto.start(ProcessesProto.SLEEP_STATUS);
17049            proto.write(ProcessesProto.SleepStatus.WAKEFULNESS,
17050                    PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
17051            for (SleepToken st : mStackSupervisor.mSleepTokens) {
17052                proto.write(ProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
17053            }
17054            proto.write(ProcessesProto.SleepStatus.SLEEPING, mSleeping);
17055            proto.write(ProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
17056            proto.write(ProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
17057            proto.end(sleepToken);
17058
17059            if (mRunningVoice != null) {
17060                final long vrToken = proto.start(ProcessesProto.RUNNING_VOICE);
17061                proto.write(ProcessesProto.VoiceProto.SESSION, mRunningVoice.toString());
17062                mVoiceWakeLock.writeToProto(proto, ProcessesProto.VoiceProto.WAKELOCK);
17063                proto.end(vrToken);
17064            }
17065
17066            mVrController.writeToProto(proto, ProcessesProto.VR_CONTROLLER);
17067        }
17068
17069        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
17070                || mOrigWaitForDebugger) {
17071            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
17072                    || dumpPackage.equals(mOrigDebugApp)) {
17073                final long debugAppToken = proto.start(ProcessesProto.DEBUG);
17074                proto.write(ProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
17075                proto.write(ProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
17076                proto.write(ProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
17077                proto.write(ProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
17078                proto.end(debugAppToken);
17079            }
17080        }
17081
17082        if (mCurAppTimeTracker != null) {
17083            mCurAppTimeTracker.writeToProto(proto, ProcessesProto.CURRENT_TRACKER, true);
17084        }
17085
17086        if (mMemWatchProcesses.getMap().size() > 0) {
17087            final long token = proto.start(ProcessesProto.MEM_WATCH_PROCESSES);
17088            ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
17089            for (int i=0; i<procs.size(); i++) {
17090                final String proc = procs.keyAt(i);
17091                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
17092                final long ptoken = proto.start(ProcessesProto.MemWatchProcess.PROCS);
17093                proto.write(ProcessesProto.MemWatchProcess.Process.NAME, proc);
17094                for (int j=0; j<uids.size(); j++) {
17095                    final long utoken = proto.start(ProcessesProto.MemWatchProcess.Process.MEM_STATS);
17096                    Pair<Long, String> val = uids.valueAt(j);
17097                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
17098                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
17099                            DebugUtils.sizeValueToString(val.first, new StringBuilder()));
17100                    proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
17101                    proto.end(utoken);
17102                }
17103                proto.end(ptoken);
17104            }
17105
17106            final long dtoken = proto.start(ProcessesProto.MemWatchProcess.DUMP);
17107            proto.write(ProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
17108            proto.write(ProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
17109            proto.write(ProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
17110            proto.write(ProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
17111            proto.end(dtoken);
17112
17113            proto.end(token);
17114        }
17115
17116        if (mTrackAllocationApp != null) {
17117            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
17118                proto.write(ProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
17119            }
17120        }
17121
17122        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
17123                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
17124            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
17125                final long token = proto.start(ProcessesProto.PROFILE);
17126                proto.write(ProcessesProto.Profile.APP_NAME, mProfileApp);
17127                mProfileProc.writeToProto(proto,ProcessesProto.Profile.PROC);
17128                if (mProfilerInfo != null) {
17129                    mProfilerInfo.writeToProto(proto, ProcessesProto.Profile.INFO);
17130                    proto.write(ProcessesProto.Profile.TYPE, mProfileType);
17131                }
17132                proto.end(token);
17133            }
17134        }
17135
17136        if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
17137            proto.write(ProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
17138        }
17139
17140        if (dumpPackage == null) {
17141            proto.write(ProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
17142            if (mController != null) {
17143                final long token = proto.start(ProcessesProto.CONTROLLER);
17144                proto.write(ProcessesProto.Controller.CONTROLLER, mController.toString());
17145                proto.write(ProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
17146                proto.end(token);
17147            }
17148            proto.write(ProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
17149            proto.write(ProcessesProto.PROCESSES_READY, mProcessesReady);
17150            proto.write(ProcessesProto.SYSTEM_READY, mSystemReady);
17151            proto.write(ProcessesProto.BOOTED, mBooted);
17152            proto.write(ProcessesProto.FACTORY_TEST, mFactoryTest);
17153            proto.write(ProcessesProto.BOOTING, mBooting);
17154            proto.write(ProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
17155            proto.write(ProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
17156            proto.write(ProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
17157            mStackSupervisor.mGoingToSleep.writeToProto(proto, ProcessesProto.GOING_TO_SLEEP);
17158            mStackSupervisor.mLaunchingActivity.writeToProto(proto, ProcessesProto.LAUNCHING_ACTIVITY);
17159            proto.write(ProcessesProto.ADJ_SEQ, mAdjSeq);
17160            proto.write(ProcessesProto.LRU_SEQ, mLruSeq);
17161            proto.write(ProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
17162            proto.write(ProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
17163            proto.write(ProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
17164            proto.write(ProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
17165            proto.write(ProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
17166            proto.write(ProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
17167            long now = SystemClock.uptimeMillis();
17168            ProtoUtils.toDuration(proto, ProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
17169            proto.write(ProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
17170        }
17171
17172    }
17173
17174    void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
17175        if (mProcessesToGc.size() > 0) {
17176            long now = SystemClock.uptimeMillis();
17177            for (int i=0; i<mProcessesToGc.size(); i++) {
17178                ProcessRecord r = mProcessesToGc.get(i);
17179                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17180                    continue;
17181                }
17182                final long token = proto.start(fieldId);
17183                r.writeToProto(proto, ProcessToGcProto.PROC);
17184                proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
17185                proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
17186                proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
17187                proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory);
17188                proto.end(token);
17189            }
17190        }
17191    }
17192
17193    boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) {
17194        if (mProcessesToGc.size() > 0) {
17195            boolean printed = false;
17196            long now = SystemClock.uptimeMillis();
17197            for (int i=0; i<mProcessesToGc.size(); i++) {
17198                ProcessRecord proc = mProcessesToGc.get(i);
17199                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
17200                    continue;
17201                }
17202                if (!printed) {
17203                    if (needSep) pw.println();
17204                    needSep = true;
17205                    pw.println("  Processes that are waiting to GC:");
17206                    printed = true;
17207                }
17208                pw.print("    Process "); pw.println(proc);
17209                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
17210                        pw.print(", last gced=");
17211                        pw.print(now-proc.lastRequestedGc);
17212                        pw.print(" ms ago, last lowMem=");
17213                        pw.print(now-proc.lastLowMemory);
17214                        pw.println(" ms ago");
17215
17216            }
17217        }
17218        return needSep;
17219    }
17220
17221    void printOomLevel(PrintWriter pw, String name, int adj) {
17222        pw.print("    ");
17223        if (adj >= 0) {
17224            pw.print(' ');
17225            if (adj < 10) pw.print(' ');
17226        } else {
17227            if (adj > -10) pw.print(' ');
17228        }
17229        pw.print(adj);
17230        pw.print(": ");
17231        pw.print(name);
17232        pw.print(" (");
17233        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
17234        pw.println(")");
17235    }
17236
17237    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17238            int opti, boolean dumpAll) {
17239        boolean needSep = false;
17240
17241        if (mLruProcesses.size() > 0) {
17242            if (needSep) pw.println();
17243            needSep = true;
17244            pw.println("  OOM levels:");
17245            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
17246            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
17247            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
17248            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
17249            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
17250            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
17251            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
17252            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
17253            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
17254            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
17255            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
17256            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
17257            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
17258            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
17259
17260            if (needSep) pw.println();
17261            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
17262                    pw.print(" total, non-act at ");
17263                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
17264                    pw.print(", non-svc at ");
17265                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
17266                    pw.println("):");
17267            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
17268            needSep = true;
17269        }
17270
17271        dumpProcessesToGc(pw, needSep, null);
17272
17273        pw.println();
17274        pw.println("  mHomeProcess: " + mHomeProcess);
17275        pw.println("  mPreviousProcess: " + mPreviousProcess);
17276        if (mHeavyWeightProcess != null) {
17277            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
17278        }
17279
17280        return true;
17281    }
17282
17283    /**
17284     * There are three ways to call this:
17285     *  - no provider specified: dump all the providers
17286     *  - a flattened component name that matched an existing provider was specified as the
17287     *    first arg: dump that one provider
17288     *  - the first arg isn't the flattened component name of an existing provider:
17289     *    dump all providers whose component contains the first arg as a substring
17290     */
17291    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17292            int opti, boolean dumpAll) {
17293        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
17294    }
17295
17296    /**
17297     * Similar to the dumpProvider, but only dumps the first matching provider.
17298     * The provider is responsible for dumping as proto.
17299     */
17300    protected boolean dumpProviderProto(FileDescriptor fd, PrintWriter pw, String name,
17301            String[] args) {
17302        return mProviderMap.dumpProviderProto(fd, pw, name, args);
17303    }
17304
17305    static class ItemMatcher {
17306        ArrayList<ComponentName> components;
17307        ArrayList<String> strings;
17308        ArrayList<Integer> objects;
17309        boolean all;
17310
17311        ItemMatcher() {
17312            all = true;
17313        }
17314
17315        void build(String name) {
17316            ComponentName componentName = ComponentName.unflattenFromString(name);
17317            if (componentName != null) {
17318                if (components == null) {
17319                    components = new ArrayList<ComponentName>();
17320                }
17321                components.add(componentName);
17322                all = false;
17323            } else {
17324                int objectId = 0;
17325                // Not a '/' separated full component name; maybe an object ID?
17326                try {
17327                    objectId = Integer.parseInt(name, 16);
17328                    if (objects == null) {
17329                        objects = new ArrayList<Integer>();
17330                    }
17331                    objects.add(objectId);
17332                    all = false;
17333                } catch (RuntimeException e) {
17334                    // Not an integer; just do string match.
17335                    if (strings == null) {
17336                        strings = new ArrayList<String>();
17337                    }
17338                    strings.add(name);
17339                    all = false;
17340                }
17341            }
17342        }
17343
17344        int build(String[] args, int opti) {
17345            for (; opti<args.length; opti++) {
17346                String name = args[opti];
17347                if ("--".equals(name)) {
17348                    return opti+1;
17349                }
17350                build(name);
17351            }
17352            return opti;
17353        }
17354
17355        boolean match(Object object, ComponentName comp) {
17356            if (all) {
17357                return true;
17358            }
17359            if (components != null) {
17360                for (int i=0; i<components.size(); i++) {
17361                    if (components.get(i).equals(comp)) {
17362                        return true;
17363                    }
17364                }
17365            }
17366            if (objects != null) {
17367                for (int i=0; i<objects.size(); i++) {
17368                    if (System.identityHashCode(object) == objects.get(i)) {
17369                        return true;
17370                    }
17371                }
17372            }
17373            if (strings != null) {
17374                String flat = comp.flattenToString();
17375                for (int i=0; i<strings.size(); i++) {
17376                    if (flat.contains(strings.get(i))) {
17377                        return true;
17378                    }
17379                }
17380            }
17381            return false;
17382        }
17383    }
17384
17385    /**
17386     * There are three things that cmd can be:
17387     *  - a flattened component name that matches an existing activity
17388     *  - the cmd arg isn't the flattened component name of an existing activity:
17389     *    dump all activity whose component contains the cmd as a substring
17390     *  - A hex number of the ActivityRecord object instance.
17391     *
17392     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
17393     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
17394     */
17395    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
17396            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
17397        ArrayList<ActivityRecord> activities;
17398
17399        synchronized (this) {
17400            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
17401                    dumpFocusedStackOnly);
17402        }
17403
17404        if (activities.size() <= 0) {
17405            return false;
17406        }
17407
17408        String[] newArgs = new String[args.length - opti];
17409        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
17410
17411        TaskRecord lastTask = null;
17412        boolean needSep = false;
17413        for (int i=activities.size()-1; i>=0; i--) {
17414            ActivityRecord r = activities.get(i);
17415            if (needSep) {
17416                pw.println();
17417            }
17418            needSep = true;
17419            synchronized (this) {
17420                final TaskRecord task = r.getTask();
17421                if (lastTask != task) {
17422                    lastTask = task;
17423                    pw.print("TASK "); pw.print(lastTask.affinity);
17424                            pw.print(" id="); pw.print(lastTask.taskId);
17425                            pw.print(" userId="); pw.println(lastTask.userId);
17426                    if (dumpAll) {
17427                        lastTask.dump(pw, "  ");
17428                    }
17429                }
17430            }
17431            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
17432        }
17433        return true;
17434    }
17435
17436    /**
17437     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
17438     * there is a thread associated with the activity.
17439     */
17440    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
17441            final ActivityRecord r, String[] args, boolean dumpAll) {
17442        String innerPrefix = prefix + "  ";
17443        synchronized (this) {
17444            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
17445                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
17446                    pw.print(" pid=");
17447                    if (r.app != null) pw.println(r.app.pid);
17448                    else pw.println("(not running)");
17449            if (dumpAll) {
17450                r.dump(pw, innerPrefix);
17451            }
17452        }
17453        if (r.app != null && r.app.thread != null) {
17454            // flush anything that is already in the PrintWriter since the thread is going
17455            // to write to the file descriptor directly
17456            pw.flush();
17457            try {
17458                TransferPipe tp = new TransferPipe();
17459                try {
17460                    r.app.thread.dumpActivity(tp.getWriteFd(),
17461                            r.appToken, innerPrefix, args);
17462                    tp.go(fd);
17463                } finally {
17464                    tp.kill();
17465                }
17466            } catch (IOException e) {
17467                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
17468            } catch (RemoteException e) {
17469                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
17470            }
17471        }
17472    }
17473
17474    void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
17475        if (mRegisteredReceivers.size() > 0) {
17476            Iterator it = mRegisteredReceivers.values().iterator();
17477            while (it.hasNext()) {
17478                ReceiverList r = (ReceiverList)it.next();
17479                r.writeToProto(proto, BroadcastProto.RECEIVER_LIST);
17480            }
17481        }
17482        mReceiverResolver.writeToProto(proto, BroadcastProto.RECEIVER_RESOLVER);
17483        for (BroadcastQueue q : mBroadcastQueues) {
17484            q.writeToProto(proto, BroadcastProto.BROADCAST_QUEUE);
17485        }
17486        for (int user=0; user<mStickyBroadcasts.size(); user++) {
17487            long token = proto.start(BroadcastProto.STICKY_BROADCASTS);
17488            proto.write(StickyBroadcastProto.USER, mStickyBroadcasts.keyAt(user));
17489            for (Map.Entry<String, ArrayList<Intent>> ent
17490                    : mStickyBroadcasts.valueAt(user).entrySet()) {
17491                long actionToken = proto.start(StickyBroadcastProto.ACTIONS);
17492                proto.write(StickyBroadcastProto.StickyAction.NAME, ent.getKey());
17493                for (Intent intent : ent.getValue()) {
17494                    intent.writeToProto(proto, StickyBroadcastProto.StickyAction.INTENTS,
17495                            false, true, true, false);
17496                }
17497                proto.end(actionToken);
17498            }
17499            proto.end(token);
17500        }
17501
17502        long handlerToken = proto.start(BroadcastProto.HANDLER);
17503        proto.write(BroadcastProto.MainHandler.HANDLER, mHandler.toString());
17504        mHandler.getLooper().writeToProto(proto, BroadcastProto.MainHandler.LOOPER);
17505        proto.end(handlerToken);
17506    }
17507
17508    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17509            int opti, boolean dumpAll, String dumpPackage) {
17510        boolean needSep = false;
17511        boolean onlyHistory = false;
17512        boolean printedAnything = false;
17513
17514        if ("history".equals(dumpPackage)) {
17515            if (opti < args.length && "-s".equals(args[opti])) {
17516                dumpAll = false;
17517            }
17518            onlyHistory = true;
17519            dumpPackage = null;
17520        }
17521
17522        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
17523        if (!onlyHistory && dumpAll) {
17524            if (mRegisteredReceivers.size() > 0) {
17525                boolean printed = false;
17526                Iterator it = mRegisteredReceivers.values().iterator();
17527                while (it.hasNext()) {
17528                    ReceiverList r = (ReceiverList)it.next();
17529                    if (dumpPackage != null && (r.app == null ||
17530                            !dumpPackage.equals(r.app.info.packageName))) {
17531                        continue;
17532                    }
17533                    if (!printed) {
17534                        pw.println("  Registered Receivers:");
17535                        needSep = true;
17536                        printed = true;
17537                        printedAnything = true;
17538                    }
17539                    pw.print("  * "); pw.println(r);
17540                    r.dump(pw, "    ");
17541                }
17542            }
17543
17544            if (mReceiverResolver.dump(pw, needSep ?
17545                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
17546                    "    ", dumpPackage, false, false)) {
17547                needSep = true;
17548                printedAnything = true;
17549            }
17550        }
17551
17552        for (BroadcastQueue q : mBroadcastQueues) {
17553            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
17554            printedAnything |= needSep;
17555        }
17556
17557        needSep = true;
17558
17559        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
17560            for (int user=0; user<mStickyBroadcasts.size(); user++) {
17561                if (needSep) {
17562                    pw.println();
17563                }
17564                needSep = true;
17565                printedAnything = true;
17566                pw.print("  Sticky broadcasts for user ");
17567                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
17568                StringBuilder sb = new StringBuilder(128);
17569                for (Map.Entry<String, ArrayList<Intent>> ent
17570                        : mStickyBroadcasts.valueAt(user).entrySet()) {
17571                    pw.print("  * Sticky action "); pw.print(ent.getKey());
17572                    if (dumpAll) {
17573                        pw.println(":");
17574                        ArrayList<Intent> intents = ent.getValue();
17575                        final int N = intents.size();
17576                        for (int i=0; i<N; i++) {
17577                            sb.setLength(0);
17578                            sb.append("    Intent: ");
17579                            intents.get(i).toShortString(sb, false, true, false, false);
17580                            pw.println(sb.toString());
17581                            Bundle bundle = intents.get(i).getExtras();
17582                            if (bundle != null) {
17583                                pw.print("      ");
17584                                pw.println(bundle.toString());
17585                            }
17586                        }
17587                    } else {
17588                        pw.println("");
17589                    }
17590                }
17591            }
17592        }
17593
17594        if (!onlyHistory && dumpAll) {
17595            pw.println();
17596            for (BroadcastQueue queue : mBroadcastQueues) {
17597                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
17598                        + queue.mBroadcastsScheduled);
17599            }
17600            pw.println("  mHandler:");
17601            mHandler.dump(new PrintWriterPrinter(pw), "    ");
17602            needSep = true;
17603            printedAnything = true;
17604        }
17605
17606        if (!printedAnything) {
17607            pw.println("  (nothing)");
17608        }
17609    }
17610
17611    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17612            int opti, boolean dumpAll, String dumpPackage) {
17613        if (mCurBroadcastStats == null) {
17614            return;
17615        }
17616
17617        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
17618        final long now = SystemClock.elapsedRealtime();
17619        if (mLastBroadcastStats != null) {
17620            pw.print("  Last stats (from ");
17621            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
17622            pw.print(" to ");
17623            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
17624            pw.print(", ");
17625            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
17626                    - mLastBroadcastStats.mStartUptime, pw);
17627            pw.println(" uptime):");
17628            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17629                pw.println("    (nothing)");
17630            }
17631            pw.println();
17632        }
17633        pw.print("  Current stats (from ");
17634        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
17635        pw.print(" to now, ");
17636        TimeUtils.formatDuration(SystemClock.uptimeMillis()
17637                - mCurBroadcastStats.mStartUptime, pw);
17638        pw.println(" uptime):");
17639        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
17640            pw.println("    (nothing)");
17641        }
17642    }
17643
17644    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17645            int opti, boolean fullCheckin, String dumpPackage) {
17646        if (mCurBroadcastStats == null) {
17647            return;
17648        }
17649
17650        if (mLastBroadcastStats != null) {
17651            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17652            if (fullCheckin) {
17653                mLastBroadcastStats = null;
17654                return;
17655            }
17656        }
17657        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
17658        if (fullCheckin) {
17659            mCurBroadcastStats = null;
17660        }
17661    }
17662
17663    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17664            int opti, boolean dumpAll, String dumpPackage) {
17665        boolean needSep;
17666        boolean printedAnything = false;
17667
17668        ItemMatcher matcher = new ItemMatcher();
17669        matcher.build(args, opti);
17670
17671        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
17672
17673        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
17674        printedAnything |= needSep;
17675
17676        if (mLaunchingProviders.size() > 0) {
17677            boolean printed = false;
17678            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
17679                ContentProviderRecord r = mLaunchingProviders.get(i);
17680                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
17681                    continue;
17682                }
17683                if (!printed) {
17684                    if (needSep) pw.println();
17685                    needSep = true;
17686                    pw.println("  Launching content providers:");
17687                    printed = true;
17688                    printedAnything = true;
17689                }
17690                pw.print("  Launching #"); pw.print(i); pw.print(": ");
17691                        pw.println(r);
17692            }
17693        }
17694
17695        if (!printedAnything) {
17696            pw.println("  (nothing)");
17697        }
17698    }
17699
17700    @GuardedBy("this")
17701    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17702            int opti, boolean dumpAll, String dumpPackage) {
17703        boolean needSep = false;
17704        boolean printedAnything = false;
17705
17706        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
17707
17708        if (mGrantedUriPermissions.size() > 0) {
17709            boolean printed = false;
17710            int dumpUid = -2;
17711            if (dumpPackage != null) {
17712                try {
17713                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
17714                            MATCH_ANY_USER, 0);
17715                } catch (NameNotFoundException e) {
17716                    dumpUid = -1;
17717                }
17718            }
17719            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
17720                int uid = mGrantedUriPermissions.keyAt(i);
17721                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
17722                    continue;
17723                }
17724                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
17725                if (!printed) {
17726                    if (needSep) pw.println();
17727                    needSep = true;
17728                    pw.println("  Granted Uri Permissions:");
17729                    printed = true;
17730                    printedAnything = true;
17731                }
17732                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
17733                for (UriPermission perm : perms.values()) {
17734                    pw.print("    "); pw.println(perm);
17735                    if (dumpAll) {
17736                        perm.dump(pw, "      ");
17737                    }
17738                }
17739            }
17740        }
17741
17742        if (!printedAnything) {
17743            pw.println("  (nothing)");
17744        }
17745    }
17746
17747    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
17748            int opti, boolean dumpAll, String dumpPackage) {
17749        boolean printed = false;
17750
17751        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
17752
17753        if (mIntentSenderRecords.size() > 0) {
17754            // Organize these by package name, so they are easier to read.
17755            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
17756            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
17757            final Iterator<WeakReference<PendingIntentRecord>> it
17758                    = mIntentSenderRecords.values().iterator();
17759            while (it.hasNext()) {
17760                WeakReference<PendingIntentRecord> ref = it.next();
17761                PendingIntentRecord rec = ref != null ? ref.get() : null;
17762                if (rec == null) {
17763                    weakRefs.add(ref);
17764                    continue;
17765                }
17766                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
17767                    continue;
17768                }
17769                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
17770                if (list == null) {
17771                    list = new ArrayList<>();
17772                    byPackage.put(rec.key.packageName, list);
17773                }
17774                list.add(rec);
17775            }
17776            for (int i = 0; i < byPackage.size(); i++) {
17777                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
17778                printed = true;
17779                pw.print("  * "); pw.print(byPackage.keyAt(i));
17780                pw.print(": "); pw.print(intents.size()); pw.println(" items");
17781                for (int j = 0; j < intents.size(); j++) {
17782                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
17783                    if (dumpAll) {
17784                        intents.get(j).dump(pw, "      ");
17785                    }
17786                }
17787            }
17788            if (weakRefs.size() > 0) {
17789                printed = true;
17790                pw.println("  * WEAK REFS:");
17791                for (int i = 0; i < weakRefs.size(); i++) {
17792                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
17793                }
17794            }
17795        }
17796
17797        if (!printed) {
17798            pw.println("  (nothing)");
17799        }
17800    }
17801
17802    private static final int dumpProcessList(PrintWriter pw,
17803            ActivityManagerService service, List list,
17804            String prefix, String normalLabel, String persistentLabel,
17805            String dumpPackage) {
17806        int numPers = 0;
17807        final int N = list.size()-1;
17808        for (int i=N; i>=0; i--) {
17809            ProcessRecord r = (ProcessRecord)list.get(i);
17810            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
17811                continue;
17812            }
17813            pw.println(String.format("%s%s #%2d: %s",
17814                    prefix, (r.persistent ? persistentLabel : normalLabel),
17815                    i, r.toString()));
17816            if (r.persistent) {
17817                numPers++;
17818            }
17819        }
17820        return numPers;
17821    }
17822
17823    private static final ArrayList<Pair<ProcessRecord, Integer>>
17824        sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) {
17825        ArrayList<Pair<ProcessRecord, Integer>> list
17826                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
17827        for (int i=0; i<origList.size(); i++) {
17828            ProcessRecord r = origList.get(i);
17829            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
17830                continue;
17831            }
17832            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
17833        }
17834
17835        Comparator<Pair<ProcessRecord, Integer>> comparator
17836                = new Comparator<Pair<ProcessRecord, Integer>>() {
17837            @Override
17838            public int compare(Pair<ProcessRecord, Integer> object1,
17839                    Pair<ProcessRecord, Integer> object2) {
17840                if (object1.first.setAdj != object2.first.setAdj) {
17841                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
17842                }
17843                if (object1.first.setProcState != object2.first.setProcState) {
17844                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
17845                }
17846                if (object1.second.intValue() != object2.second.intValue()) {
17847                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
17848                }
17849                return 0;
17850            }
17851        };
17852
17853        Collections.sort(list, comparator);
17854        return list;
17855    }
17856
17857    private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
17858            ActivityManagerService service, List<ProcessRecord> origList,
17859            boolean inclDetails, String dumpPackage) {
17860        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
17861        if (list.isEmpty()) return false;
17862
17863        final long curUptime = SystemClock.uptimeMillis();
17864
17865        for (int i = list.size() - 1; i >= 0; i--) {
17866            ProcessRecord r = list.get(i).first;
17867            long token = proto.start(fieldId);
17868            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
17869            proto.write(ProcessOomProto.PERSISTENT, r.persistent);
17870            proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
17871            proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
17872            int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
17873            switch (r.setSchedGroup) {
17874                case ProcessList.SCHED_GROUP_BACKGROUND:
17875                    schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
17876                    break;
17877                case ProcessList.SCHED_GROUP_DEFAULT:
17878                    schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
17879                    break;
17880                case ProcessList.SCHED_GROUP_TOP_APP:
17881                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
17882                    break;
17883                case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
17884                    schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
17885                    break;
17886            }
17887            if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
17888                proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
17889            }
17890            if (r.foregroundActivities) {
17891                proto.write(ProcessOomProto.ACTIVITIES, true);
17892            } else if (r.foregroundServices) {
17893                proto.write(ProcessOomProto.SERVICES, true);
17894            }
17895            proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
17896            proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
17897            r.writeToProto(proto, ProcessOomProto.PROC);
17898            proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
17899            if (r.adjSource != null || r.adjTarget != null) {
17900                if (r.adjTarget instanceof  ComponentName) {
17901                    ComponentName cn = (ComponentName) r.adjTarget;
17902                    cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
17903                } else if (r.adjTarget != null) {
17904                    proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
17905                }
17906                if (r.adjSource instanceof ProcessRecord) {
17907                    ProcessRecord p = (ProcessRecord) r.adjSource;
17908                    p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
17909                } else if (r.adjSource != null) {
17910                    proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
17911                }
17912            }
17913            if (inclDetails) {
17914                long detailToken = proto.start(ProcessOomProto.DETAIL);
17915                proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
17916                proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
17917                proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
17918                proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
17919                proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
17920                proto.write(ProcessOomProto.Detail.CURRENT_STATE,
17921                        ProcessList.makeProcStateProtoEnum(r.curProcState));
17922                proto.write(ProcessOomProto.Detail.SET_STATE,
17923                        ProcessList.makeProcStateProtoEnum(r.setProcState));
17924                proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
17925                        r.lastPss*1024, new StringBuilder()));
17926                proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
17927                        r.lastSwapPss*1024, new StringBuilder()));
17928                proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
17929                        r.lastCachedPss*1024, new StringBuilder()));
17930                proto.write(ProcessOomProto.Detail.CACHED, r.cached);
17931                proto.write(ProcessOomProto.Detail.EMPTY, r.empty);
17932                proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient);
17933
17934                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
17935                    if (r.lastCpuTime != 0) {
17936                        long uptimeSince = curUptime - service.mLastPowerCheckUptime;
17937                        long timeUsed = r.curCpuTime - r.lastCpuTime;
17938                        long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
17939                        proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
17940                        proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
17941                        proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
17942                                (100.0*timeUsed)/uptimeSince);
17943                        proto.end(cpuTimeToken);
17944                    }
17945                }
17946                proto.end(detailToken);
17947            }
17948            proto.end(token);
17949        }
17950
17951        return true;
17952    }
17953
17954    private static final boolean dumpProcessOomList(PrintWriter pw,
17955            ActivityManagerService service, List<ProcessRecord> origList,
17956            String prefix, String normalLabel, String persistentLabel,
17957            boolean inclDetails, String dumpPackage) {
17958
17959        ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
17960        if (list.isEmpty()) return false;
17961
17962        final long curUptime = SystemClock.uptimeMillis();
17963        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
17964
17965        for (int i=list.size()-1; i>=0; i--) {
17966            ProcessRecord r = list.get(i).first;
17967            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
17968            char schedGroup;
17969            switch (r.setSchedGroup) {
17970                case ProcessList.SCHED_GROUP_BACKGROUND:
17971                    schedGroup = 'B';
17972                    break;
17973                case ProcessList.SCHED_GROUP_DEFAULT:
17974                    schedGroup = 'F';
17975                    break;
17976                case ProcessList.SCHED_GROUP_TOP_APP:
17977                    schedGroup = 'T';
17978                    break;
17979                default:
17980                    schedGroup = '?';
17981                    break;
17982            }
17983            char foreground;
17984            if (r.foregroundActivities) {
17985                foreground = 'A';
17986            } else if (r.foregroundServices) {
17987                foreground = 'S';
17988            } else {
17989                foreground = ' ';
17990            }
17991            String procState = ProcessList.makeProcStateString(r.curProcState);
17992            pw.print(prefix);
17993            pw.print(r.persistent ? persistentLabel : normalLabel);
17994            pw.print(" #");
17995            int num = (origList.size()-1)-list.get(i).second;
17996            if (num < 10) pw.print(' ');
17997            pw.print(num);
17998            pw.print(": ");
17999            pw.print(oomAdj);
18000            pw.print(' ');
18001            pw.print(schedGroup);
18002            pw.print('/');
18003            pw.print(foreground);
18004            pw.print('/');
18005            pw.print(procState);
18006            pw.print(" trm:");
18007            if (r.trimMemoryLevel < 10) pw.print(' ');
18008            pw.print(r.trimMemoryLevel);
18009            pw.print(' ');
18010            pw.print(r.toShortString());
18011            pw.print(" (");
18012            pw.print(r.adjType);
18013            pw.println(')');
18014            if (r.adjSource != null || r.adjTarget != null) {
18015                pw.print(prefix);
18016                pw.print("    ");
18017                if (r.adjTarget instanceof ComponentName) {
18018                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
18019                } else if (r.adjTarget != null) {
18020                    pw.print(r.adjTarget.toString());
18021                } else {
18022                    pw.print("{null}");
18023                }
18024                pw.print("<=");
18025                if (r.adjSource instanceof ProcessRecord) {
18026                    pw.print("Proc{");
18027                    pw.print(((ProcessRecord)r.adjSource).toShortString());
18028                    pw.println("}");
18029                } else if (r.adjSource != null) {
18030                    pw.println(r.adjSource.toString());
18031                } else {
18032                    pw.println("{null}");
18033                }
18034            }
18035            if (inclDetails) {
18036                pw.print(prefix);
18037                pw.print("    ");
18038                pw.print("oom: max="); pw.print(r.maxAdj);
18039                pw.print(" curRaw="); pw.print(r.curRawAdj);
18040                pw.print(" setRaw="); pw.print(r.setRawAdj);
18041                pw.print(" cur="); pw.print(r.curAdj);
18042                pw.print(" set="); pw.println(r.setAdj);
18043                pw.print(prefix);
18044                pw.print("    ");
18045                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
18046                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
18047                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
18048                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
18049                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
18050                pw.println();
18051                pw.print(prefix);
18052                pw.print("    ");
18053                pw.print("cached="); pw.print(r.cached);
18054                pw.print(" empty="); pw.print(r.empty);
18055                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
18056
18057                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
18058                    if (r.lastCpuTime != 0) {
18059                        long timeUsed = r.curCpuTime - r.lastCpuTime;
18060                        pw.print(prefix);
18061                        pw.print("    ");
18062                        pw.print("run cpu over ");
18063                        TimeUtils.formatDuration(uptimeSince, pw);
18064                        pw.print(" used ");
18065                        TimeUtils.formatDuration(timeUsed, pw);
18066                        pw.print(" (");
18067                        pw.print((timeUsed*100)/uptimeSince);
18068                        pw.println("%)");
18069                    }
18070                }
18071            }
18072        }
18073        return true;
18074    }
18075
18076    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
18077            String[] args) {
18078        ArrayList<ProcessRecord> procs;
18079        synchronized (this) {
18080            if (args != null && args.length > start
18081                    && args[start].charAt(0) != '-') {
18082                procs = new ArrayList<ProcessRecord>();
18083                int pid = -1;
18084                try {
18085                    pid = Integer.parseInt(args[start]);
18086                } catch (NumberFormatException e) {
18087                }
18088                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18089                    ProcessRecord proc = mLruProcesses.get(i);
18090                    if (proc.pid > 0 && proc.pid == pid) {
18091                        procs.add(proc);
18092                    } else if (allPkgs && proc.pkgList != null
18093                            && proc.pkgList.containsKey(args[start])) {
18094                        procs.add(proc);
18095                    } else if (proc.processName.equals(args[start])) {
18096                        procs.add(proc);
18097                    }
18098                }
18099                if (procs.size() <= 0) {
18100                    return null;
18101                }
18102            } else {
18103                procs = new ArrayList<ProcessRecord>(mLruProcesses);
18104            }
18105        }
18106        return procs;
18107    }
18108
18109    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
18110            PrintWriter pw, String[] args) {
18111        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18112        if (procs == null) {
18113            pw.println("No process found for: " + args[0]);
18114            return;
18115        }
18116
18117        long uptime = SystemClock.uptimeMillis();
18118        long realtime = SystemClock.elapsedRealtime();
18119        pw.println("Applications Graphics Acceleration Info:");
18120        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18121
18122        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18123            ProcessRecord r = procs.get(i);
18124            if (r.thread != null) {
18125                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
18126                pw.flush();
18127                try {
18128                    TransferPipe tp = new TransferPipe();
18129                    try {
18130                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
18131                        tp.go(fd);
18132                    } finally {
18133                        tp.kill();
18134                    }
18135                } catch (IOException e) {
18136                    pw.println("Failure while dumping the app: " + r);
18137                    pw.flush();
18138                } catch (RemoteException e) {
18139                    pw.println("Got a RemoteException while dumping the app " + r);
18140                    pw.flush();
18141                }
18142            }
18143        }
18144    }
18145
18146    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
18147        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
18148        if (procs == null) {
18149            pw.println("No process found for: " + args[0]);
18150            return;
18151        }
18152
18153        pw.println("Applications Database Info:");
18154
18155        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18156            ProcessRecord r = procs.get(i);
18157            if (r.thread != null) {
18158                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
18159                pw.flush();
18160                try {
18161                    TransferPipe tp = new TransferPipe();
18162                    try {
18163                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
18164                        tp.go(fd);
18165                    } finally {
18166                        tp.kill();
18167                    }
18168                } catch (IOException e) {
18169                    pw.println("Failure while dumping the app: " + r);
18170                    pw.flush();
18171                } catch (RemoteException e) {
18172                    pw.println("Got a RemoteException while dumping the app " + r);
18173                    pw.flush();
18174                }
18175            }
18176        }
18177    }
18178
18179    final static class MemItem {
18180        final boolean isProc;
18181        final String label;
18182        final String shortLabel;
18183        final long pss;
18184        final long swapPss;
18185        final int id;
18186        final boolean hasActivities;
18187        ArrayList<MemItem> subitems;
18188
18189        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
18190                boolean _hasActivities) {
18191            isProc = true;
18192            label = _label;
18193            shortLabel = _shortLabel;
18194            pss = _pss;
18195            swapPss = _swapPss;
18196            id = _id;
18197            hasActivities = _hasActivities;
18198        }
18199
18200        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
18201            isProc = false;
18202            label = _label;
18203            shortLabel = _shortLabel;
18204            pss = _pss;
18205            swapPss = _swapPss;
18206            id = _id;
18207            hasActivities = false;
18208        }
18209    }
18210
18211    private static void sortMemItems(List<MemItem> items) {
18212        Collections.sort(items, new Comparator<MemItem>() {
18213            @Override
18214            public int compare(MemItem lhs, MemItem rhs) {
18215                if (lhs.pss < rhs.pss) {
18216                    return 1;
18217                } else if (lhs.pss > rhs.pss) {
18218                    return -1;
18219                }
18220                return 0;
18221            }
18222        });
18223    }
18224
18225    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
18226            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
18227        if (sort && !isCompact) {
18228            sortMemItems(items);
18229        }
18230
18231        for (int i=0; i<items.size(); i++) {
18232            MemItem mi = items.get(i);
18233            if (!isCompact) {
18234                if (dumpSwapPss) {
18235                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
18236                            mi.label, stringifyKBSize(mi.swapPss));
18237                } else {
18238                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
18239                }
18240            } else if (mi.isProc) {
18241                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
18242                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
18243                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
18244                pw.println(mi.hasActivities ? ",a" : ",e");
18245            } else {
18246                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
18247                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
18248            }
18249            if (mi.subitems != null) {
18250                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
18251                        true, isCompact, dumpSwapPss);
18252            }
18253        }
18254    }
18255
18256    static final void dumpMemItems(ProtoOutputStream proto, long fieldId, String tag,
18257            ArrayList<MemItem> items, boolean sort, boolean dumpSwapPss) {
18258        if (sort) {
18259            sortMemItems(items);
18260        }
18261
18262        for (int i=0; i<items.size(); i++) {
18263            MemItem mi = items.get(i);
18264            final long token = proto.start(fieldId);
18265
18266            proto.write(MemInfoProto.MemItem.TAG, tag);
18267            proto.write(MemInfoProto.MemItem.LABEL, mi.shortLabel);
18268            proto.write(MemInfoProto.MemItem.IS_PROC, mi.isProc);
18269            proto.write(MemInfoProto.MemItem.ID, mi.id);
18270            proto.write(MemInfoProto.MemItem.HAS_ACTIVITIES, mi.hasActivities);
18271            proto.write(MemInfoProto.MemItem.PSS_KB, mi.pss);
18272            if (dumpSwapPss) {
18273                proto.write(MemInfoProto.MemItem.SWAP_PSS_KB, mi.swapPss);
18274            }
18275            if (mi.subitems != null) {
18276                dumpMemItems(proto, MemInfoProto.MemItem.SUB_ITEMS, mi.shortLabel, mi.subitems,
18277                        true, dumpSwapPss);
18278            }
18279            proto.end(token);
18280        }
18281    }
18282
18283    // These are in KB.
18284    static final long[] DUMP_MEM_BUCKETS = new long[] {
18285        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
18286        120*1024, 160*1024, 200*1024,
18287        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
18288        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
18289    };
18290
18291    static final void appendMemBucket(StringBuilder out, long memKB, String label,
18292            boolean stackLike) {
18293        int start = label.lastIndexOf('.');
18294        if (start >= 0) start++;
18295        else start = 0;
18296        int end = label.length();
18297        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
18298            if (DUMP_MEM_BUCKETS[i] >= memKB) {
18299                long bucket = DUMP_MEM_BUCKETS[i]/1024;
18300                out.append(bucket);
18301                out.append(stackLike ? "MB." : "MB ");
18302                out.append(label, start, end);
18303                return;
18304            }
18305        }
18306        out.append(memKB/1024);
18307        out.append(stackLike ? "MB." : "MB ");
18308        out.append(label, start, end);
18309    }
18310
18311    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
18312            ProcessList.NATIVE_ADJ,
18313            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
18314            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
18315            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
18316            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
18317            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
18318            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
18319    };
18320    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
18321            "Native",
18322            "System", "Persistent", "Persistent Service", "Foreground",
18323            "Visible", "Perceptible",
18324            "Heavy Weight", "Backup",
18325            "A Services", "Home",
18326            "Previous", "B Services", "Cached"
18327    };
18328    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
18329            "native",
18330            "sys", "pers", "persvc", "fore",
18331            "vis", "percept",
18332            "heavy", "backup",
18333            "servicea", "home",
18334            "prev", "serviceb", "cached"
18335    };
18336
18337    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
18338            long realtime, boolean isCheckinRequest, boolean isCompact) {
18339        if (isCompact) {
18340            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
18341        }
18342        if (isCheckinRequest || isCompact) {
18343            // short checkin version
18344            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
18345        } else {
18346            pw.println("Applications Memory Usage (in Kilobytes):");
18347            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
18348        }
18349    }
18350
18351    private static final int KSM_SHARED = 0;
18352    private static final int KSM_SHARING = 1;
18353    private static final int KSM_UNSHARED = 2;
18354    private static final int KSM_VOLATILE = 3;
18355
18356    private final long[] getKsmInfo() {
18357        long[] longOut = new long[4];
18358        final int[] SINGLE_LONG_FORMAT = new int[] {
18359            PROC_SPACE_TERM| PROC_OUT_LONG
18360        };
18361        long[] longTmp = new long[1];
18362        readProcFile("/sys/kernel/mm/ksm/pages_shared",
18363                SINGLE_LONG_FORMAT, null, longTmp, null);
18364        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18365        longTmp[0] = 0;
18366        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
18367                SINGLE_LONG_FORMAT, null, longTmp, null);
18368        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18369        longTmp[0] = 0;
18370        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
18371                SINGLE_LONG_FORMAT, null, longTmp, null);
18372        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18373        longTmp[0] = 0;
18374        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
18375                SINGLE_LONG_FORMAT, null, longTmp, null);
18376        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
18377        return longOut;
18378    }
18379
18380    private static String stringifySize(long size, int order) {
18381        Locale locale = Locale.US;
18382        switch (order) {
18383            case 1:
18384                return String.format(locale, "%,13d", size);
18385            case 1024:
18386                return String.format(locale, "%,9dK", size / 1024);
18387            case 1024 * 1024:
18388                return String.format(locale, "%,5dM", size / 1024 / 1024);
18389            case 1024 * 1024 * 1024:
18390                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
18391            default:
18392                throw new IllegalArgumentException("Invalid size order");
18393        }
18394    }
18395
18396    private static String stringifyKBSize(long size) {
18397        return stringifySize(size * 1024, 1024);
18398    }
18399
18400    // Update this version number if you change the 'compact' format.
18401    private static final int MEMINFO_COMPACT_VERSION = 1;
18402
18403    private static class MemoryUsageDumpOptions {
18404        boolean dumpDetails;
18405        boolean dumpFullDetails;
18406        boolean dumpDalvik;
18407        boolean dumpSummaryOnly;
18408        boolean dumpUnreachable;
18409        boolean oomOnly;
18410        boolean isCompact;
18411        boolean localOnly;
18412        boolean packages;
18413        boolean isCheckinRequest;
18414        boolean dumpSwapPss;
18415        boolean dumpProto;
18416    }
18417
18418    final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18419            String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) {
18420        MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions();
18421        opts.dumpDetails = false;
18422        opts.dumpFullDetails = false;
18423        opts.dumpDalvik = false;
18424        opts.dumpSummaryOnly = false;
18425        opts.dumpUnreachable = false;
18426        opts.oomOnly = false;
18427        opts.isCompact = false;
18428        opts.localOnly = false;
18429        opts.packages = false;
18430        opts.isCheckinRequest = false;
18431        opts.dumpSwapPss = false;
18432        opts.dumpProto = asProto;
18433
18434        int opti = 0;
18435        while (opti < args.length) {
18436            String opt = args[opti];
18437            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
18438                break;
18439            }
18440            opti++;
18441            if ("-a".equals(opt)) {
18442                opts.dumpDetails = true;
18443                opts.dumpFullDetails = true;
18444                opts.dumpDalvik = true;
18445                opts.dumpSwapPss = true;
18446            } else if ("-d".equals(opt)) {
18447                opts.dumpDalvik = true;
18448            } else if ("-c".equals(opt)) {
18449                opts.isCompact = true;
18450            } else if ("-s".equals(opt)) {
18451                opts.dumpDetails = true;
18452                opts.dumpSummaryOnly = true;
18453            } else if ("-S".equals(opt)) {
18454                opts.dumpSwapPss = true;
18455            } else if ("--unreachable".equals(opt)) {
18456                opts.dumpUnreachable = true;
18457            } else if ("--oom".equals(opt)) {
18458                opts.oomOnly = true;
18459            } else if ("--local".equals(opt)) {
18460                opts.localOnly = true;
18461            } else if ("--package".equals(opt)) {
18462                opts.packages = true;
18463            } else if ("--checkin".equals(opt)) {
18464                opts.isCheckinRequest = true;
18465            } else if ("--proto".equals(opt)) {
18466                opts.dumpProto = true;
18467
18468            } else if ("-h".equals(opt)) {
18469                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
18470                pw.println("  -a: include all available information for each process.");
18471                pw.println("  -d: include dalvik details.");
18472                pw.println("  -c: dump in a compact machine-parseable representation.");
18473                pw.println("  -s: dump only summary of application memory usage.");
18474                pw.println("  -S: dump also SwapPss.");
18475                pw.println("  --oom: only show processes organized by oom adj.");
18476                pw.println("  --local: only collect details locally, don't call process.");
18477                pw.println("  --package: interpret process arg as package, dumping all");
18478                pw.println("             processes that have loaded that package.");
18479                pw.println("  --checkin: dump data for a checkin");
18480                pw.println("  --proto: dump data to proto");
18481                pw.println("If [process] is specified it can be the name or ");
18482                pw.println("pid of a specific process to dump.");
18483                return;
18484            } else {
18485                pw.println("Unknown argument: " + opt + "; use -h for help");
18486            }
18487        }
18488
18489        String[] innerArgs = new String[args.length-opti];
18490        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
18491
18492        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, opts.packages, args);
18493        if (opts.dumpProto) {
18494            dumpApplicationMemoryUsage(fd, opts, innerArgs, brief, procs);
18495        } else {
18496            dumpApplicationMemoryUsage(fd, pw, prefix, opts, innerArgs, brief, procs, categoryPw);
18497        }
18498    }
18499
18500    private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix,
18501            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18502            ArrayList<ProcessRecord> procs, PrintWriter categoryPw) {
18503        long uptime = SystemClock.uptimeMillis();
18504        long realtime = SystemClock.elapsedRealtime();
18505        final long[] tmpLong = new long[1];
18506
18507        if (procs == null) {
18508            // No Java processes.  Maybe they want to print a native process.
18509            String proc = "N/A";
18510            if (innerArgs.length > 0) {
18511                proc = innerArgs[0];
18512                if (proc.charAt(0) != '-') {
18513                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
18514                            = new ArrayList<ProcessCpuTracker.Stats>();
18515                    updateCpuStatsNow();
18516                    int findPid = -1;
18517                    try {
18518                        findPid = Integer.parseInt(innerArgs[0]);
18519                    } catch (NumberFormatException e) {
18520                    }
18521                    synchronized (mProcessCpuTracker) {
18522                        final int N = mProcessCpuTracker.countStats();
18523                        for (int i=0; i<N; i++) {
18524                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18525                            if (st.pid == findPid || (st.baseName != null
18526                                    && st.baseName.equals(innerArgs[0]))) {
18527                                nativeProcs.add(st);
18528                            }
18529                        }
18530                    }
18531                    if (nativeProcs.size() > 0) {
18532                        dumpApplicationMemoryUsageHeader(pw, uptime, realtime,
18533                                opts.isCheckinRequest, opts.isCompact);
18534                        Debug.MemoryInfo mi = null;
18535                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
18536                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
18537                            final int pid = r.pid;
18538                            if (!opts.isCheckinRequest && opts.dumpDetails) {
18539                                pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
18540                            }
18541                            if (mi == null) {
18542                                mi = new Debug.MemoryInfo();
18543                            }
18544                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18545                                Debug.getMemoryInfo(pid, mi);
18546                            } else {
18547                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18548                                mi.dalvikPrivateDirty = (int)tmpLong[0];
18549                            }
18550                            ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest,
18551                                    opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
18552                                    pid, r.baseName, 0, 0, 0, 0, 0, 0);
18553                            if (opts.isCheckinRequest) {
18554                                pw.println();
18555                            }
18556                        }
18557                        return;
18558                    }
18559                }
18560            }
18561            pw.println("No process found for: " + proc);
18562            return;
18563        }
18564
18565        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
18566            opts.dumpDetails = true;
18567        }
18568
18569        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact);
18570
18571        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
18572        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
18573        long nativePss = 0;
18574        long nativeSwapPss = 0;
18575        long dalvikPss = 0;
18576        long dalvikSwapPss = 0;
18577        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18578                EmptyArray.LONG;
18579        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
18580                EmptyArray.LONG;
18581        long otherPss = 0;
18582        long otherSwapPss = 0;
18583        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18584        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
18585
18586        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18587        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
18588        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
18589                new ArrayList[DUMP_MEM_OOM_LABEL.length];
18590
18591        long totalPss = 0;
18592        long totalSwapPss = 0;
18593        long cachedPss = 0;
18594        long cachedSwapPss = 0;
18595        boolean hasSwapPss = false;
18596
18597        Debug.MemoryInfo mi = null;
18598        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
18599            final ProcessRecord r = procs.get(i);
18600            final IApplicationThread thread;
18601            final int pid;
18602            final int oomAdj;
18603            final boolean hasActivities;
18604            synchronized (this) {
18605                thread = r.thread;
18606                pid = r.pid;
18607                oomAdj = r.getSetAdjWithServices();
18608                hasActivities = r.activities.size() > 0;
18609            }
18610            if (thread != null) {
18611                if (!opts.isCheckinRequest && opts.dumpDetails) {
18612                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
18613                }
18614                if (mi == null) {
18615                    mi = new Debug.MemoryInfo();
18616                }
18617                final int reportType;
18618                final long startTime;
18619                final long endTime;
18620                if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
18621                    reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
18622                    startTime = SystemClock.currentThreadTimeMillis();
18623                    Debug.getMemoryInfo(pid, mi);
18624                    endTime = SystemClock.currentThreadTimeMillis();
18625                    hasSwapPss = mi.hasSwappedOutPss;
18626                } else {
18627                    reportType = ProcessStats.ADD_PSS_EXTERNAL;
18628                    startTime = SystemClock.currentThreadTimeMillis();
18629                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
18630                    endTime = SystemClock.currentThreadTimeMillis();
18631                    mi.dalvikPrivateDirty = (int)tmpLong[0];
18632                }
18633                if (opts.dumpDetails) {
18634                    if (opts.localOnly) {
18635                        ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
18636                                opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
18637                        if (opts.isCheckinRequest) {
18638                            pw.println();
18639                        }
18640                    } else {
18641                        pw.flush();
18642                        try {
18643                            TransferPipe tp = new TransferPipe();
18644                            try {
18645                                thread.dumpMemInfo(tp.getWriteFd(),
18646                                        mi, opts.isCheckinRequest, opts.dumpFullDetails,
18647                                        opts.dumpDalvik, opts.dumpSummaryOnly, opts.dumpUnreachable, innerArgs);
18648                                tp.go(fd);
18649                            } finally {
18650                                tp.kill();
18651                            }
18652                        } catch (IOException e) {
18653                            if (!opts.isCheckinRequest) {
18654                                pw.println("Got IoException! " + e);
18655                                pw.flush();
18656                            }
18657                        } catch (RemoteException e) {
18658                            if (!opts.isCheckinRequest) {
18659                                pw.println("Got RemoteException! " + e);
18660                                pw.flush();
18661                            }
18662                        }
18663                    }
18664                }
18665
18666                final long myTotalPss = mi.getTotalPss();
18667                final long myTotalUss = mi.getTotalUss();
18668                final long myTotalRss = mi.getTotalRss();
18669                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18670
18671                synchronized (this) {
18672                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
18673                        // Record this for posterity if the process has been stable.
18674                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
18675                                reportType, endTime-startTime, r.pkgList);
18676                    }
18677                }
18678
18679                if (!opts.isCheckinRequest && mi != null) {
18680                    totalPss += myTotalPss;
18681                    totalSwapPss += myTotalSwapPss;
18682                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
18683                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
18684                            myTotalSwapPss, pid, hasActivities);
18685                    procMems.add(pssItem);
18686                    procMemsMap.put(pid, pssItem);
18687
18688                    nativePss += mi.nativePss;
18689                    nativeSwapPss += mi.nativeSwappedOutPss;
18690                    dalvikPss += mi.dalvikPss;
18691                    dalvikSwapPss += mi.dalvikSwappedOutPss;
18692                    for (int j=0; j<dalvikSubitemPss.length; j++) {
18693                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18694                        dalvikSubitemSwapPss[j] +=
18695                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18696                    }
18697                    otherPss += mi.otherPss;
18698                    otherSwapPss += mi.otherSwappedOutPss;
18699                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18700                        long mem = mi.getOtherPss(j);
18701                        miscPss[j] += mem;
18702                        otherPss -= mem;
18703                        mem = mi.getOtherSwappedOutPss(j);
18704                        miscSwapPss[j] += mem;
18705                        otherSwapPss -= mem;
18706                    }
18707
18708                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
18709                        cachedPss += myTotalPss;
18710                        cachedSwapPss += myTotalSwapPss;
18711                    }
18712
18713                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
18714                        if (oomIndex == (oomPss.length - 1)
18715                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
18716                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
18717                            oomPss[oomIndex] += myTotalPss;
18718                            oomSwapPss[oomIndex] += myTotalSwapPss;
18719                            if (oomProcs[oomIndex] == null) {
18720                                oomProcs[oomIndex] = new ArrayList<MemItem>();
18721                            }
18722                            oomProcs[oomIndex].add(pssItem);
18723                            break;
18724                        }
18725                    }
18726                }
18727            }
18728        }
18729
18730        long nativeProcTotalPss = 0;
18731
18732        if (!opts.isCheckinRequest && procs.size() > 1 && !opts.packages) {
18733            // If we are showing aggregations, also look for native processes to
18734            // include so that our aggregations are more accurate.
18735            updateCpuStatsNow();
18736            mi = null;
18737            synchronized (mProcessCpuTracker) {
18738                final int N = mProcessCpuTracker.countStats();
18739                for (int i=0; i<N; i++) {
18740                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
18741                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
18742                        if (mi == null) {
18743                            mi = new Debug.MemoryInfo();
18744                        }
18745                        if (!brief && !opts.oomOnly) {
18746                            Debug.getMemoryInfo(st.pid, mi);
18747                        } else {
18748                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
18749                            mi.nativePrivateDirty = (int)tmpLong[0];
18750                        }
18751
18752                        final long myTotalPss = mi.getTotalPss();
18753                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
18754                        totalPss += myTotalPss;
18755                        totalSwapPss += myTotalSwapPss;
18756                        nativeProcTotalPss += myTotalPss;
18757
18758                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
18759                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
18760                        procMems.add(pssItem);
18761
18762                        nativePss += mi.nativePss;
18763                        nativeSwapPss += mi.nativeSwappedOutPss;
18764                        dalvikPss += mi.dalvikPss;
18765                        dalvikSwapPss += mi.dalvikSwappedOutPss;
18766                        for (int j=0; j<dalvikSubitemPss.length; j++) {
18767                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18768                            dalvikSubitemSwapPss[j] +=
18769                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
18770                        }
18771                        otherPss += mi.otherPss;
18772                        otherSwapPss += mi.otherSwappedOutPss;
18773                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18774                            long mem = mi.getOtherPss(j);
18775                            miscPss[j] += mem;
18776                            otherPss -= mem;
18777                            mem = mi.getOtherSwappedOutPss(j);
18778                            miscSwapPss[j] += mem;
18779                            otherSwapPss -= mem;
18780                        }
18781                        oomPss[0] += myTotalPss;
18782                        oomSwapPss[0] += myTotalSwapPss;
18783                        if (oomProcs[0] == null) {
18784                            oomProcs[0] = new ArrayList<MemItem>();
18785                        }
18786                        oomProcs[0].add(pssItem);
18787                    }
18788                }
18789            }
18790
18791            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
18792
18793            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
18794            final int dalvikId = -2;
18795            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
18796            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
18797            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
18798                String label = Debug.MemoryInfo.getOtherLabel(j);
18799                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
18800            }
18801            if (dalvikSubitemPss.length > 0) {
18802                // Add dalvik subitems.
18803                for (MemItem memItem : catMems) {
18804                    int memItemStart = 0, memItemEnd = 0;
18805                    if (memItem.id == dalvikId) {
18806                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
18807                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
18808                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
18809                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
18810                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
18811                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
18812                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
18813                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
18814                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
18815                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
18816                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
18817                    } else {
18818                        continue;  // No subitems, continue.
18819                    }
18820                    memItem.subitems = new ArrayList<MemItem>();
18821                    for (int j=memItemStart; j<=memItemEnd; j++) {
18822                        final String name = Debug.MemoryInfo.getOtherLabel(
18823                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
18824                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
18825                                dalvikSubitemSwapPss[j], j));
18826                    }
18827                }
18828            }
18829
18830            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
18831            for (int j=0; j<oomPss.length; j++) {
18832                if (oomPss[j] != 0) {
18833                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
18834                            : DUMP_MEM_OOM_LABEL[j];
18835                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
18836                            DUMP_MEM_OOM_ADJ[j]);
18837                    item.subitems = oomProcs[j];
18838                    oomMems.add(item);
18839                }
18840            }
18841
18842            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
18843            if (!brief && !opts.oomOnly && !opts.isCompact) {
18844                pw.println();
18845                pw.println("Total PSS by process:");
18846                dumpMemItems(pw, "  ", "proc", procMems, true, opts.isCompact, opts.dumpSwapPss);
18847                pw.println();
18848            }
18849            if (!opts.isCompact) {
18850                pw.println("Total PSS by OOM adjustment:");
18851            }
18852            dumpMemItems(pw, "  ", "oom", oomMems, false, opts.isCompact, opts.dumpSwapPss);
18853            if (!brief && !opts.oomOnly) {
18854                PrintWriter out = categoryPw != null ? categoryPw : pw;
18855                if (!opts.isCompact) {
18856                    out.println();
18857                    out.println("Total PSS by category:");
18858                }
18859                dumpMemItems(out, "  ", "cat", catMems, true, opts.isCompact, opts.dumpSwapPss);
18860            }
18861            if (!opts.isCompact) {
18862                pw.println();
18863            }
18864            MemInfoReader memInfo = new MemInfoReader();
18865            memInfo.readMemInfo();
18866            if (nativeProcTotalPss > 0) {
18867                synchronized (this) {
18868                    final long cachedKb = memInfo.getCachedSizeKb();
18869                    final long freeKb = memInfo.getFreeSizeKb();
18870                    final long zramKb = memInfo.getZramTotalSizeKb();
18871                    final long kernelKb = memInfo.getKernelUsedSizeKb();
18872                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
18873                            kernelKb*1024, nativeProcTotalPss*1024);
18874                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
18875                            nativeProcTotalPss);
18876                }
18877            }
18878            if (!brief) {
18879                if (!opts.isCompact) {
18880                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
18881                    pw.print(" (status ");
18882                    switch (mLastMemoryLevel) {
18883                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
18884                            pw.println("normal)");
18885                            break;
18886                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
18887                            pw.println("moderate)");
18888                            break;
18889                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
18890                            pw.println("low)");
18891                            break;
18892                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18893                            pw.println("critical)");
18894                            break;
18895                        default:
18896                            pw.print(mLastMemoryLevel);
18897                            pw.println(")");
18898                            break;
18899                    }
18900                    pw.print(" Free RAM: ");
18901                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
18902                            + memInfo.getFreeSizeKb()));
18903                    pw.print(" (");
18904                    pw.print(stringifyKBSize(cachedPss));
18905                    pw.print(" cached pss + ");
18906                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
18907                    pw.print(" cached kernel + ");
18908                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
18909                    pw.println(" free)");
18910                } else {
18911                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
18912                    pw.print(cachedPss + memInfo.getCachedSizeKb()
18913                            + memInfo.getFreeSizeKb()); pw.print(",");
18914                    pw.println(totalPss - cachedPss);
18915                }
18916            }
18917            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
18918                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
18919                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
18920            if (!opts.isCompact) {
18921                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
18922                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
18923                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
18924                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
18925                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
18926            } else {
18927                pw.print("lostram,"); pw.println(lostRAM);
18928            }
18929            if (!brief) {
18930                if (memInfo.getZramTotalSizeKb() != 0) {
18931                    if (!opts.isCompact) {
18932                        pw.print("     ZRAM: ");
18933                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
18934                                pw.print(" physical used for ");
18935                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
18936                                        - memInfo.getSwapFreeSizeKb()));
18937                                pw.print(" in swap (");
18938                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
18939                                pw.println(" total swap)");
18940                    } else {
18941                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
18942                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
18943                                pw.println(memInfo.getSwapFreeSizeKb());
18944                    }
18945                }
18946                final long[] ksm = getKsmInfo();
18947                if (!opts.isCompact) {
18948                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
18949                            || ksm[KSM_VOLATILE] != 0) {
18950                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
18951                                pw.print(" saved from shared ");
18952                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
18953                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
18954                                pw.print(" unshared; ");
18955                                pw.print(stringifyKBSize(
18956                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
18957                    }
18958                    pw.print("   Tuning: ");
18959                    pw.print(ActivityManager.staticGetMemoryClass());
18960                    pw.print(" (large ");
18961                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18962                    pw.print("), oom ");
18963                    pw.print(stringifySize(
18964                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
18965                    pw.print(", restore limit ");
18966                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
18967                    if (ActivityManager.isLowRamDeviceStatic()) {
18968                        pw.print(" (low-ram)");
18969                    }
18970                    if (ActivityManager.isHighEndGfx()) {
18971                        pw.print(" (high-end-gfx)");
18972                    }
18973                    pw.println();
18974                } else {
18975                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
18976                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
18977                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
18978                    pw.print("tuning,");
18979                    pw.print(ActivityManager.staticGetMemoryClass());
18980                    pw.print(',');
18981                    pw.print(ActivityManager.staticGetLargeMemoryClass());
18982                    pw.print(',');
18983                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
18984                    if (ActivityManager.isLowRamDeviceStatic()) {
18985                        pw.print(",low-ram");
18986                    }
18987                    if (ActivityManager.isHighEndGfx()) {
18988                        pw.print(",high-end-gfx");
18989                    }
18990                    pw.println();
18991                }
18992            }
18993        }
18994    }
18995
18996    private final void dumpApplicationMemoryUsage(FileDescriptor fd,
18997            MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief,
18998            ArrayList<ProcessRecord> procs) {
18999        final long uptimeMs = SystemClock.uptimeMillis();
19000        final long realtimeMs = SystemClock.elapsedRealtime();
19001        final long[] tmpLong = new long[1];
19002
19003        if (procs == null) {
19004            // No Java processes.  Maybe they want to print a native process.
19005            String proc = "N/A";
19006            if (innerArgs.length > 0) {
19007                proc = innerArgs[0];
19008                if (proc.charAt(0) != '-') {
19009                    ArrayList<ProcessCpuTracker.Stats> nativeProcs
19010                            = new ArrayList<ProcessCpuTracker.Stats>();
19011                    updateCpuStatsNow();
19012                    int findPid = -1;
19013                    try {
19014                        findPid = Integer.parseInt(innerArgs[0]);
19015                    } catch (NumberFormatException e) {
19016                    }
19017                    synchronized (mProcessCpuTracker) {
19018                        final int N = mProcessCpuTracker.countStats();
19019                        for (int i=0; i<N; i++) {
19020                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19021                            if (st.pid == findPid || (st.baseName != null
19022                                    && st.baseName.equals(innerArgs[0]))) {
19023                                nativeProcs.add(st);
19024                            }
19025                        }
19026                    }
19027                    if (nativeProcs.size() > 0) {
19028                        ProtoOutputStream proto = new ProtoOutputStream(fd);
19029
19030                        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
19031                        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
19032                        Debug.MemoryInfo mi = null;
19033                        for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
19034                            final ProcessCpuTracker.Stats r = nativeProcs.get(i);
19035                            final int pid = r.pid;
19036                            final long nToken = proto.start(MemInfoProto.NATIVE_PROCESSES);
19037
19038                            proto.write(MemInfoProto.ProcessMemory.PID, pid);
19039                            proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.baseName);
19040
19041                            if (mi == null) {
19042                                mi = new Debug.MemoryInfo();
19043                            }
19044                            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19045                                Debug.getMemoryInfo(pid, mi);
19046                            } else {
19047                                mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
19048                                mi.dalvikPrivateDirty = (int)tmpLong[0];
19049                            }
19050                            ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19051                                    opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19052
19053                            proto.end(nToken);
19054                        }
19055
19056                        proto.flush();
19057                        return;
19058                    }
19059                }
19060            }
19061            Log.d(TAG, "No process found for: " + innerArgs[0]);
19062            return;
19063        }
19064
19065        if (!brief && !opts.oomOnly && (procs.size() == 1 || opts.isCheckinRequest || opts.packages)) {
19066            opts.dumpDetails = true;
19067        }
19068
19069        ProtoOutputStream proto = new ProtoOutputStream(fd);
19070
19071        proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs);
19072        proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs);
19073
19074        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
19075        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
19076        long nativePss = 0;
19077        long nativeSwapPss = 0;
19078        long dalvikPss = 0;
19079        long dalvikSwapPss = 0;
19080        long[] dalvikSubitemPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19081                EmptyArray.LONG;
19082        long[] dalvikSubitemSwapPss = opts.dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
19083                EmptyArray.LONG;
19084        long otherPss = 0;
19085        long otherSwapPss = 0;
19086        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19087        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
19088
19089        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19090        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
19091        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
19092                new ArrayList[DUMP_MEM_OOM_LABEL.length];
19093
19094        long totalPss = 0;
19095        long totalSwapPss = 0;
19096        long cachedPss = 0;
19097        long cachedSwapPss = 0;
19098        boolean hasSwapPss = false;
19099
19100        Debug.MemoryInfo mi = null;
19101        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
19102            final ProcessRecord r = procs.get(i);
19103            final IApplicationThread thread;
19104            final int pid;
19105            final int oomAdj;
19106            final boolean hasActivities;
19107            synchronized (this) {
19108                thread = r.thread;
19109                pid = r.pid;
19110                oomAdj = r.getSetAdjWithServices();
19111                hasActivities = r.activities.size() > 0;
19112            }
19113            if (thread == null) {
19114                continue;
19115            }
19116            if (mi == null) {
19117                mi = new Debug.MemoryInfo();
19118            }
19119            final int reportType;
19120            final long startTime;
19121            final long endTime;
19122            if (opts.dumpDetails || (!brief && !opts.oomOnly)) {
19123                reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW;
19124                startTime = SystemClock.currentThreadTimeMillis();
19125                Debug.getMemoryInfo(pid, mi);
19126                endTime = SystemClock.currentThreadTimeMillis();
19127                hasSwapPss = mi.hasSwappedOutPss;
19128            } else {
19129                reportType = ProcessStats.ADD_PSS_EXTERNAL;
19130                startTime = SystemClock.currentThreadTimeMillis();
19131                mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null);
19132                endTime = SystemClock.currentThreadTimeMillis();
19133                mi.dalvikPrivateDirty = (int) tmpLong[0];
19134            }
19135            if (opts.dumpDetails) {
19136                if (opts.localOnly) {
19137                    final long aToken = proto.start(MemInfoProto.APP_PROCESSES);
19138                    final long mToken = proto.start(MemInfoProto.AppData.PROCESS_MEMORY);
19139                    proto.write(MemInfoProto.ProcessMemory.PID, pid);
19140                    proto.write(MemInfoProto.ProcessMemory.PROCESS_NAME, r.processName);
19141                    ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik,
19142                            opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0);
19143                    proto.end(mToken);
19144                    proto.end(aToken);
19145                } else {
19146                    try {
19147                        ByteTransferPipe tp = new ByteTransferPipe();
19148                        try {
19149                            thread.dumpMemInfoProto(tp.getWriteFd(),
19150                                mi, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
19151                                opts.dumpUnreachable, innerArgs);
19152                            proto.write(MemInfoProto.APP_PROCESSES, tp.get());
19153                        } finally {
19154                            tp.kill();
19155                        }
19156                    } catch (IOException e) {
19157                        Log.e(TAG, "Got IOException!", e);
19158                    } catch (RemoteException e) {
19159                        Log.e(TAG, "Got RemoteException!", e);
19160                    }
19161                }
19162            }
19163
19164            final long myTotalPss = mi.getTotalPss();
19165            final long myTotalUss = mi.getTotalUss();
19166            final long myTotalRss = mi.getTotalRss();
19167            final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19168
19169            synchronized (this) {
19170                if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
19171                    // Record this for posterity if the process has been stable.
19172                    r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
19173                            reportType, endTime-startTime, r.pkgList);
19174                }
19175            }
19176
19177            if (!opts.isCheckinRequest && mi != null) {
19178                totalPss += myTotalPss;
19179                totalSwapPss += myTotalSwapPss;
19180                MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
19181                        (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
19182                        myTotalSwapPss, pid, hasActivities);
19183                procMems.add(pssItem);
19184                procMemsMap.put(pid, pssItem);
19185
19186                nativePss += mi.nativePss;
19187                nativeSwapPss += mi.nativeSwappedOutPss;
19188                dalvikPss += mi.dalvikPss;
19189                dalvikSwapPss += mi.dalvikSwappedOutPss;
19190                for (int j=0; j<dalvikSubitemPss.length; j++) {
19191                    dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19192                    dalvikSubitemSwapPss[j] +=
19193                            mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19194                }
19195                otherPss += mi.otherPss;
19196                otherSwapPss += mi.otherSwappedOutPss;
19197                for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19198                    long mem = mi.getOtherPss(j);
19199                    miscPss[j] += mem;
19200                    otherPss -= mem;
19201                    mem = mi.getOtherSwappedOutPss(j);
19202                    miscSwapPss[j] += mem;
19203                    otherSwapPss -= mem;
19204                }
19205
19206                if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19207                    cachedPss += myTotalPss;
19208                    cachedSwapPss += myTotalSwapPss;
19209                }
19210
19211                for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
19212                    if (oomIndex == (oomPss.length - 1)
19213                            || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
19214                                    && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
19215                        oomPss[oomIndex] += myTotalPss;
19216                        oomSwapPss[oomIndex] += myTotalSwapPss;
19217                        if (oomProcs[oomIndex] == null) {
19218                            oomProcs[oomIndex] = new ArrayList<MemItem>();
19219                        }
19220                        oomProcs[oomIndex].add(pssItem);
19221                        break;
19222                    }
19223                }
19224            }
19225        }
19226
19227        long nativeProcTotalPss = 0;
19228
19229        if (procs.size() > 1 && !opts.packages) {
19230            // If we are showing aggregations, also look for native processes to
19231            // include so that our aggregations are more accurate.
19232            updateCpuStatsNow();
19233            mi = null;
19234            synchronized (mProcessCpuTracker) {
19235                final int N = mProcessCpuTracker.countStats();
19236                for (int i=0; i<N; i++) {
19237                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
19238                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
19239                        if (mi == null) {
19240                            mi = new Debug.MemoryInfo();
19241                        }
19242                        if (!brief && !opts.oomOnly) {
19243                            Debug.getMemoryInfo(st.pid, mi);
19244                        } else {
19245                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
19246                            mi.nativePrivateDirty = (int)tmpLong[0];
19247                        }
19248
19249                        final long myTotalPss = mi.getTotalPss();
19250                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
19251                        totalPss += myTotalPss;
19252                        nativeProcTotalPss += myTotalPss;
19253
19254                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
19255                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
19256                        procMems.add(pssItem);
19257
19258                        nativePss += mi.nativePss;
19259                        nativeSwapPss += mi.nativeSwappedOutPss;
19260                        dalvikPss += mi.dalvikPss;
19261                        dalvikSwapPss += mi.dalvikSwappedOutPss;
19262                        for (int j=0; j<dalvikSubitemPss.length; j++) {
19263                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19264                            dalvikSubitemSwapPss[j] +=
19265                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
19266                        }
19267                        otherPss += mi.otherPss;
19268                        otherSwapPss += mi.otherSwappedOutPss;
19269                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19270                            long mem = mi.getOtherPss(j);
19271                            miscPss[j] += mem;
19272                            otherPss -= mem;
19273                            mem = mi.getOtherSwappedOutPss(j);
19274                            miscSwapPss[j] += mem;
19275                            otherSwapPss -= mem;
19276                        }
19277                        oomPss[0] += myTotalPss;
19278                        oomSwapPss[0] += myTotalSwapPss;
19279                        if (oomProcs[0] == null) {
19280                            oomProcs[0] = new ArrayList<MemItem>();
19281                        }
19282                        oomProcs[0].add(pssItem);
19283                    }
19284                }
19285            }
19286
19287            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
19288
19289            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
19290            final int dalvikId = -2;
19291            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
19292            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
19293            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
19294                String label = Debug.MemoryInfo.getOtherLabel(j);
19295                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
19296            }
19297            if (dalvikSubitemPss.length > 0) {
19298                // Add dalvik subitems.
19299                for (MemItem memItem : catMems) {
19300                    int memItemStart = 0, memItemEnd = 0;
19301                    if (memItem.id == dalvikId) {
19302                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
19303                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
19304                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
19305                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
19306                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
19307                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
19308                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
19309                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
19310                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
19311                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
19312                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
19313                    } else {
19314                        continue;  // No subitems, continue.
19315                    }
19316                    memItem.subitems = new ArrayList<MemItem>();
19317                    for (int j=memItemStart; j<=memItemEnd; j++) {
19318                        final String name = Debug.MemoryInfo.getOtherLabel(
19319                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
19320                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
19321                                dalvikSubitemSwapPss[j], j));
19322                    }
19323                }
19324            }
19325
19326            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
19327            for (int j=0; j<oomPss.length; j++) {
19328                if (oomPss[j] != 0) {
19329                    String label = opts.isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
19330                            : DUMP_MEM_OOM_LABEL[j];
19331                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
19332                            DUMP_MEM_OOM_ADJ[j]);
19333                    item.subitems = oomProcs[j];
19334                    oomMems.add(item);
19335                }
19336            }
19337
19338            opts.dumpSwapPss = opts.dumpSwapPss && hasSwapPss && totalSwapPss != 0;
19339            if (!opts.oomOnly) {
19340                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_PROCESS, "proc",
19341                        procMems, true, opts.dumpSwapPss);
19342            }
19343            dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_OOM_ADJUSTMENT, "oom",
19344                    oomMems, false, opts.dumpSwapPss);
19345            if (!brief && !opts.oomOnly) {
19346                dumpMemItems(proto, MemInfoProto.TOTAL_PSS_BY_CATEGORY, "cat",
19347                        catMems, true, opts.dumpSwapPss);
19348            }
19349            MemInfoReader memInfo = new MemInfoReader();
19350            memInfo.readMemInfo();
19351            if (nativeProcTotalPss > 0) {
19352                synchronized (this) {
19353                    final long cachedKb = memInfo.getCachedSizeKb();
19354                    final long freeKb = memInfo.getFreeSizeKb();
19355                    final long zramKb = memInfo.getZramTotalSizeKb();
19356                    final long kernelKb = memInfo.getKernelUsedSizeKb();
19357                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
19358                            kernelKb*1024, nativeProcTotalPss*1024);
19359                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
19360                            nativeProcTotalPss);
19361                }
19362            }
19363            if (!brief) {
19364                proto.write(MemInfoProto.TOTAL_RAM_KB, memInfo.getTotalSizeKb());
19365                proto.write(MemInfoProto.STATUS, mLastMemoryLevel);
19366                proto.write(MemInfoProto.CACHED_PSS_KB, cachedPss);
19367                proto.write(MemInfoProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
19368                proto.write(MemInfoProto.FREE_KB, memInfo.getFreeSizeKb());
19369            }
19370            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
19371                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19372                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
19373            proto.write(MemInfoProto.USED_PSS_KB, totalPss - cachedPss);
19374            proto.write(MemInfoProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
19375            proto.write(MemInfoProto.LOST_RAM_KB, lostRAM);
19376            if (!brief) {
19377                if (memInfo.getZramTotalSizeKb() != 0) {
19378                    proto.write(MemInfoProto.TOTAL_ZRAM_KB, memInfo.getZramTotalSizeKb());
19379                    proto.write(MemInfoProto.ZRAM_PHYSICAL_USED_IN_SWAP_KB,
19380                            memInfo.getSwapTotalSizeKb() - memInfo.getSwapFreeSizeKb());
19381                    proto.write(MemInfoProto.TOTAL_ZRAM_SWAP_KB, memInfo.getSwapTotalSizeKb());
19382                }
19383                final long[] ksm = getKsmInfo();
19384                proto.write(MemInfoProto.KSM_SHARING_KB, ksm[KSM_SHARING]);
19385                proto.write(MemInfoProto.KSM_SHARED_KB, ksm[KSM_SHARED]);
19386                proto.write(MemInfoProto.KSM_UNSHARED_KB, ksm[KSM_UNSHARED]);
19387                proto.write(MemInfoProto.KSM_VOLATILE_KB, ksm[KSM_VOLATILE]);
19388
19389                proto.write(MemInfoProto.TUNING_MB, ActivityManager.staticGetMemoryClass());
19390                proto.write(MemInfoProto.TUNING_LARGE_MB, ActivityManager.staticGetLargeMemoryClass());
19391                proto.write(MemInfoProto.OOM_KB,
19392                        mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024);
19393                proto.write(MemInfoProto.RESTORE_LIMIT_KB,
19394                        mProcessList.getCachedRestoreThresholdKb());
19395
19396                proto.write(MemInfoProto.IS_LOW_RAM_DEVICE, ActivityManager.isLowRamDeviceStatic());
19397                proto.write(MemInfoProto.IS_HIGH_END_GFX, ActivityManager.isHighEndGfx());
19398            }
19399        }
19400
19401        proto.flush();
19402    }
19403
19404    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
19405            long memtrack, String name) {
19406        sb.append("  ");
19407        sb.append(ProcessList.makeOomAdjString(oomAdj));
19408        sb.append(' ');
19409        sb.append(ProcessList.makeProcStateString(procState));
19410        sb.append(' ');
19411        ProcessList.appendRamKb(sb, pss);
19412        sb.append(": ");
19413        sb.append(name);
19414        if (memtrack > 0) {
19415            sb.append(" (");
19416            sb.append(stringifyKBSize(memtrack));
19417            sb.append(" memtrack)");
19418        }
19419    }
19420
19421    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
19422        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
19423        sb.append(" (pid ");
19424        sb.append(mi.pid);
19425        sb.append(") ");
19426        sb.append(mi.adjType);
19427        sb.append('\n');
19428        if (mi.adjReason != null) {
19429            sb.append("                      ");
19430            sb.append(mi.adjReason);
19431            sb.append('\n');
19432        }
19433    }
19434
19435    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
19436        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
19437        for (int i=0, N=memInfos.size(); i<N; i++) {
19438            ProcessMemInfo mi = memInfos.get(i);
19439            infoMap.put(mi.pid, mi);
19440        }
19441        updateCpuStatsNow();
19442        long[] memtrackTmp = new long[1];
19443        final List<ProcessCpuTracker.Stats> stats;
19444        // Get a list of Stats that have vsize > 0
19445        synchronized (mProcessCpuTracker) {
19446            stats = mProcessCpuTracker.getStats((st) -> {
19447                return st.vsize > 0;
19448            });
19449        }
19450        final int statsCount = stats.size();
19451        for (int i = 0; i < statsCount; i++) {
19452            ProcessCpuTracker.Stats st = stats.get(i);
19453            long pss = Debug.getPss(st.pid, null, memtrackTmp);
19454            if (pss > 0) {
19455                if (infoMap.indexOfKey(st.pid) < 0) {
19456                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
19457                            ProcessList.NATIVE_ADJ, -1, "native", null);
19458                    mi.pss = pss;
19459                    mi.memtrack = memtrackTmp[0];
19460                    memInfos.add(mi);
19461                }
19462            }
19463        }
19464
19465        long totalPss = 0;
19466        long totalMemtrack = 0;
19467        for (int i=0, N=memInfos.size(); i<N; i++) {
19468            ProcessMemInfo mi = memInfos.get(i);
19469            if (mi.pss == 0) {
19470                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
19471                mi.memtrack = memtrackTmp[0];
19472            }
19473            totalPss += mi.pss;
19474            totalMemtrack += mi.memtrack;
19475        }
19476        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
19477            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
19478                if (lhs.oomAdj != rhs.oomAdj) {
19479                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
19480                }
19481                if (lhs.pss != rhs.pss) {
19482                    return lhs.pss < rhs.pss ? 1 : -1;
19483                }
19484                return 0;
19485            }
19486        });
19487
19488        StringBuilder tag = new StringBuilder(128);
19489        StringBuilder stack = new StringBuilder(128);
19490        tag.append("Low on memory -- ");
19491        appendMemBucket(tag, totalPss, "total", false);
19492        appendMemBucket(stack, totalPss, "total", true);
19493
19494        StringBuilder fullNativeBuilder = new StringBuilder(1024);
19495        StringBuilder shortNativeBuilder = new StringBuilder(1024);
19496        StringBuilder fullJavaBuilder = new StringBuilder(1024);
19497
19498        boolean firstLine = true;
19499        int lastOomAdj = Integer.MIN_VALUE;
19500        long extraNativeRam = 0;
19501        long extraNativeMemtrack = 0;
19502        long cachedPss = 0;
19503        for (int i=0, N=memInfos.size(); i<N; i++) {
19504            ProcessMemInfo mi = memInfos.get(i);
19505
19506            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
19507                cachedPss += mi.pss;
19508            }
19509
19510            if (mi.oomAdj != ProcessList.NATIVE_ADJ
19511                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
19512                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
19513                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
19514                if (lastOomAdj != mi.oomAdj) {
19515                    lastOomAdj = mi.oomAdj;
19516                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19517                        tag.append(" / ");
19518                    }
19519                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
19520                        if (firstLine) {
19521                            stack.append(":");
19522                            firstLine = false;
19523                        }
19524                        stack.append("\n\t at ");
19525                    } else {
19526                        stack.append("$");
19527                    }
19528                } else {
19529                    tag.append(" ");
19530                    stack.append("$");
19531                }
19532                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19533                    appendMemBucket(tag, mi.pss, mi.name, false);
19534                }
19535                appendMemBucket(stack, mi.pss, mi.name, true);
19536                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
19537                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
19538                    stack.append("(");
19539                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
19540                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
19541                            stack.append(DUMP_MEM_OOM_LABEL[k]);
19542                            stack.append(":");
19543                            stack.append(DUMP_MEM_OOM_ADJ[k]);
19544                        }
19545                    }
19546                    stack.append(")");
19547                }
19548            }
19549
19550            appendMemInfo(fullNativeBuilder, mi);
19551            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
19552                // The short form only has native processes that are >= 512K.
19553                if (mi.pss >= 512) {
19554                    appendMemInfo(shortNativeBuilder, mi);
19555                } else {
19556                    extraNativeRam += mi.pss;
19557                    extraNativeMemtrack += mi.memtrack;
19558                }
19559            } else {
19560                // Short form has all other details, but if we have collected RAM
19561                // from smaller native processes let's dump a summary of that.
19562                if (extraNativeRam > 0) {
19563                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
19564                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
19565                    shortNativeBuilder.append('\n');
19566                    extraNativeRam = 0;
19567                }
19568                appendMemInfo(fullJavaBuilder, mi);
19569            }
19570        }
19571
19572        fullJavaBuilder.append("           ");
19573        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
19574        fullJavaBuilder.append(": TOTAL");
19575        if (totalMemtrack > 0) {
19576            fullJavaBuilder.append(" (");
19577            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
19578            fullJavaBuilder.append(" memtrack)");
19579        } else {
19580        }
19581        fullJavaBuilder.append("\n");
19582
19583        MemInfoReader memInfo = new MemInfoReader();
19584        memInfo.readMemInfo();
19585        final long[] infos = memInfo.getRawInfo();
19586
19587        StringBuilder memInfoBuilder = new StringBuilder(1024);
19588        Debug.getMemInfo(infos);
19589        memInfoBuilder.append("  MemInfo: ");
19590        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
19591        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
19592        memInfoBuilder.append(stringifyKBSize(
19593                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
19594        memInfoBuilder.append(stringifyKBSize(
19595                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
19596        memInfoBuilder.append(stringifyKBSize(
19597                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
19598        memInfoBuilder.append("           ");
19599        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
19600        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
19601        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
19602        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
19603        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
19604            memInfoBuilder.append("  ZRAM: ");
19605            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
19606            memInfoBuilder.append(" RAM, ");
19607            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
19608            memInfoBuilder.append(" swap total, ");
19609            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
19610            memInfoBuilder.append(" swap free\n");
19611        }
19612        final long[] ksm = getKsmInfo();
19613        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
19614                || ksm[KSM_VOLATILE] != 0) {
19615            memInfoBuilder.append("  KSM: ");
19616            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
19617            memInfoBuilder.append(" saved from shared ");
19618            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
19619            memInfoBuilder.append("\n       ");
19620            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
19621            memInfoBuilder.append(" unshared; ");
19622            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
19623            memInfoBuilder.append(" volatile\n");
19624        }
19625        memInfoBuilder.append("  Free RAM: ");
19626        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
19627                + memInfo.getFreeSizeKb()));
19628        memInfoBuilder.append("\n");
19629        memInfoBuilder.append("  Used RAM: ");
19630        memInfoBuilder.append(stringifyKBSize(
19631                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
19632        memInfoBuilder.append("\n");
19633        memInfoBuilder.append("  Lost RAM: ");
19634        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
19635                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
19636                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
19637        memInfoBuilder.append("\n");
19638        Slog.i(TAG, "Low on memory:");
19639        Slog.i(TAG, shortNativeBuilder.toString());
19640        Slog.i(TAG, fullJavaBuilder.toString());
19641        Slog.i(TAG, memInfoBuilder.toString());
19642
19643        StringBuilder dropBuilder = new StringBuilder(1024);
19644        /*
19645        StringWriter oomSw = new StringWriter();
19646        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
19647        StringWriter catSw = new StringWriter();
19648        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19649        String[] emptyArgs = new String[] { };
19650        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
19651        oomPw.flush();
19652        String oomString = oomSw.toString();
19653        */
19654        dropBuilder.append("Low on memory:");
19655        dropBuilder.append(stack);
19656        dropBuilder.append('\n');
19657        dropBuilder.append(fullNativeBuilder);
19658        dropBuilder.append(fullJavaBuilder);
19659        dropBuilder.append('\n');
19660        dropBuilder.append(memInfoBuilder);
19661        dropBuilder.append('\n');
19662        /*
19663        dropBuilder.append(oomString);
19664        dropBuilder.append('\n');
19665        */
19666        StringWriter catSw = new StringWriter();
19667        synchronized (ActivityManagerService.this) {
19668            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
19669            String[] emptyArgs = new String[] { };
19670            catPw.println();
19671            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null, -1);
19672            catPw.println();
19673            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
19674                    false, null).dumpLocked();
19675            catPw.println();
19676            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
19677            catPw.flush();
19678        }
19679        dropBuilder.append(catSw.toString());
19680        addErrorToDropBox("lowmem", null, "system_server", null,
19681                null, tag.toString(), dropBuilder.toString(), null, null);
19682        //Slog.i(TAG, "Sent to dropbox:");
19683        //Slog.i(TAG, dropBuilder.toString());
19684        synchronized (ActivityManagerService.this) {
19685            long now = SystemClock.uptimeMillis();
19686            if (mLastMemUsageReportTime < now) {
19687                mLastMemUsageReportTime = now;
19688            }
19689        }
19690    }
19691
19692    /**
19693     * Searches array of arguments for the specified string
19694     * @param args array of argument strings
19695     * @param value value to search for
19696     * @return true if the value is contained in the array
19697     */
19698    private static boolean scanArgs(String[] args, String value) {
19699        if (args != null) {
19700            for (String arg : args) {
19701                if (value.equals(arg)) {
19702                    return true;
19703                }
19704            }
19705        }
19706        return false;
19707    }
19708
19709    private final boolean removeDyingProviderLocked(ProcessRecord proc,
19710            ContentProviderRecord cpr, boolean always) {
19711        final boolean inLaunching = mLaunchingProviders.contains(cpr);
19712
19713        if (!inLaunching || always) {
19714            synchronized (cpr) {
19715                cpr.launchingApp = null;
19716                cpr.notifyAll();
19717            }
19718            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
19719            String names[] = cpr.info.authority.split(";");
19720            for (int j = 0; j < names.length; j++) {
19721                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
19722            }
19723        }
19724
19725        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
19726            ContentProviderConnection conn = cpr.connections.get(i);
19727            if (conn.waiting) {
19728                // If this connection is waiting for the provider, then we don't
19729                // need to mess with its process unless we are always removing
19730                // or for some reason the provider is not currently launching.
19731                if (inLaunching && !always) {
19732                    continue;
19733                }
19734            }
19735            ProcessRecord capp = conn.client;
19736            conn.dead = true;
19737            if (conn.stableCount > 0) {
19738                if (!capp.persistent && capp.thread != null
19739                        && capp.pid != 0
19740                        && capp.pid != MY_PID) {
19741                    capp.kill("depends on provider "
19742                            + cpr.name.flattenToShortString()
19743                            + " in dying proc " + (proc != null ? proc.processName : "??")
19744                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
19745                }
19746            } else if (capp.thread != null && conn.provider.provider != null) {
19747                try {
19748                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
19749                } catch (RemoteException e) {
19750                }
19751                // In the protocol here, we don't expect the client to correctly
19752                // clean up this connection, we'll just remove it.
19753                cpr.connections.remove(i);
19754                if (conn.client.conProviders.remove(conn)) {
19755                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
19756                }
19757            }
19758        }
19759
19760        if (inLaunching && always) {
19761            mLaunchingProviders.remove(cpr);
19762        }
19763        return inLaunching;
19764    }
19765
19766    /**
19767     * Main code for cleaning up a process when it has gone away.  This is
19768     * called both as a result of the process dying, or directly when stopping
19769     * a process when running in single process mode.
19770     *
19771     * @return Returns true if the given process has been restarted, so the
19772     * app that was passed in must remain on the process lists.
19773     */
19774    @GuardedBy("this")
19775    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
19776            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
19777        if (index >= 0) {
19778            removeLruProcessLocked(app);
19779            ProcessList.remove(app.pid);
19780        }
19781
19782        mProcessesToGc.remove(app);
19783        mPendingPssProcesses.remove(app);
19784        ProcessList.abortNextPssTime(app.procStateMemTracker);
19785
19786        // Dismiss any open dialogs.
19787        if (app.crashDialog != null && !app.forceCrashReport) {
19788            app.crashDialog.dismiss();
19789            app.crashDialog = null;
19790        }
19791        if (app.anrDialog != null) {
19792            app.anrDialog.dismiss();
19793            app.anrDialog = null;
19794        }
19795        if (app.waitDialog != null) {
19796            app.waitDialog.dismiss();
19797            app.waitDialog = null;
19798        }
19799
19800        app.crashing = false;
19801        app.notResponding = false;
19802
19803        app.resetPackageList(mProcessStats);
19804        app.unlinkDeathRecipient();
19805        app.makeInactive(mProcessStats);
19806        app.waitingToKill = null;
19807        app.forcingToImportant = null;
19808        updateProcessForegroundLocked(app, false, false);
19809        app.foregroundActivities = false;
19810        app.hasShownUi = false;
19811        app.treatLikeActivity = false;
19812        app.hasAboveClient = false;
19813        app.hasClientActivities = false;
19814
19815        mServices.killServicesLocked(app, allowRestart);
19816
19817        boolean restart = false;
19818
19819        // Remove published content providers.
19820        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
19821            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
19822            final boolean always = app.bad || !allowRestart;
19823            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
19824            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
19825                // We left the provider in the launching list, need to
19826                // restart it.
19827                restart = true;
19828            }
19829
19830            cpr.provider = null;
19831            cpr.proc = null;
19832        }
19833        app.pubProviders.clear();
19834
19835        // Take care of any launching providers waiting for this process.
19836        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
19837            restart = true;
19838        }
19839
19840        // Unregister from connected content providers.
19841        if (!app.conProviders.isEmpty()) {
19842            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
19843                ContentProviderConnection conn = app.conProviders.get(i);
19844                conn.provider.connections.remove(conn);
19845                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
19846                        conn.provider.name);
19847            }
19848            app.conProviders.clear();
19849        }
19850
19851        // At this point there may be remaining entries in mLaunchingProviders
19852        // where we were the only one waiting, so they are no longer of use.
19853        // Look for these and clean up if found.
19854        // XXX Commented out for now.  Trying to figure out a way to reproduce
19855        // the actual situation to identify what is actually going on.
19856        if (false) {
19857            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19858                ContentProviderRecord cpr = mLaunchingProviders.get(i);
19859                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
19860                    synchronized (cpr) {
19861                        cpr.launchingApp = null;
19862                        cpr.notifyAll();
19863                    }
19864                }
19865            }
19866        }
19867
19868        skipCurrentReceiverLocked(app);
19869
19870        // Unregister any receivers.
19871        for (int i = app.receivers.size() - 1; i >= 0; i--) {
19872            removeReceiverLocked(app.receivers.valueAt(i));
19873        }
19874        app.receivers.clear();
19875
19876        // If the app is undergoing backup, tell the backup manager about it
19877        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
19878            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
19879                    + mBackupTarget.appInfo + " died during backup");
19880            mHandler.post(new Runnable() {
19881                @Override
19882                public void run(){
19883                    try {
19884                        IBackupManager bm = IBackupManager.Stub.asInterface(
19885                                ServiceManager.getService(Context.BACKUP_SERVICE));
19886                        bm.agentDisconnected(app.info.packageName);
19887                    } catch (RemoteException e) {
19888                        // can't happen; backup manager is local
19889                    }
19890                }
19891            });
19892        }
19893
19894        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
19895            ProcessChangeItem item = mPendingProcessChanges.get(i);
19896            if (app.pid > 0 && item.pid == app.pid) {
19897                mPendingProcessChanges.remove(i);
19898                mAvailProcessChanges.add(item);
19899            }
19900        }
19901        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
19902                null).sendToTarget();
19903
19904        // If the caller is restarting this app, then leave it in its
19905        // current lists and let the caller take care of it.
19906        if (restarting) {
19907            return false;
19908        }
19909
19910        if (!app.persistent || app.isolated) {
19911            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
19912                    "Removing non-persistent process during cleanup: " + app);
19913            if (!replacingPid) {
19914                removeProcessNameLocked(app.processName, app.uid, app);
19915            }
19916            if (mHeavyWeightProcess == app) {
19917                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
19918                        mHeavyWeightProcess.userId, 0));
19919                mHeavyWeightProcess = null;
19920            }
19921        } else if (!app.removed) {
19922            // This app is persistent, so we need to keep its record around.
19923            // If it is not already on the pending app list, add it there
19924            // and start a new process for it.
19925            if (mPersistentStartingProcesses.indexOf(app) < 0) {
19926                mPersistentStartingProcesses.add(app);
19927                restart = true;
19928            }
19929        }
19930        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
19931                TAG_CLEANUP, "Clean-up removing on hold: " + app);
19932        mProcessesOnHold.remove(app);
19933
19934        if (app == mHomeProcess) {
19935            mHomeProcess = null;
19936        }
19937        if (app == mPreviousProcess) {
19938            mPreviousProcess = null;
19939        }
19940
19941        if (restart && !app.isolated) {
19942            // We have components that still need to be running in the
19943            // process, so re-launch it.
19944            if (index < 0) {
19945                ProcessList.remove(app.pid);
19946            }
19947            addProcessNameLocked(app);
19948            app.pendingStart = false;
19949            startProcessLocked(app, "restart", app.processName);
19950            return true;
19951        } else if (app.pid > 0 && app.pid != MY_PID) {
19952            // Goodbye!
19953            boolean removed;
19954            synchronized (mPidsSelfLocked) {
19955                mPidsSelfLocked.remove(app.pid);
19956                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
19957            }
19958            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
19959            if (app.isolated) {
19960                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
19961            }
19962            app.setPid(0);
19963        }
19964        return false;
19965    }
19966
19967    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
19968        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19969            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19970            if (cpr.launchingApp == app) {
19971                return true;
19972            }
19973        }
19974        return false;
19975    }
19976
19977    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
19978        // Look through the content providers we are waiting to have launched,
19979        // and if any run in this process then either schedule a restart of
19980        // the process or kill the client waiting for it if this process has
19981        // gone bad.
19982        boolean restart = false;
19983        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
19984            ContentProviderRecord cpr = mLaunchingProviders.get(i);
19985            if (cpr.launchingApp == app) {
19986                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
19987                    restart = true;
19988                } else {
19989                    removeDyingProviderLocked(app, cpr, true);
19990                }
19991            }
19992        }
19993        return restart;
19994    }
19995
19996    // =========================================================
19997    // SERVICES
19998    // =========================================================
19999
20000    @Override
20001    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) {
20002        enforceNotIsolatedCaller("getServices");
20003
20004        final int callingUid = Binder.getCallingUid();
20005        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
20006            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
20007        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
20008            callingUid);
20009        synchronized (this) {
20010            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
20011                allowed, canInteractAcrossUsers);
20012        }
20013    }
20014
20015    @Override
20016    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
20017        enforceNotIsolatedCaller("getRunningServiceControlPanel");
20018        synchronized (this) {
20019            return mServices.getRunningServiceControlPanelLocked(name);
20020        }
20021    }
20022
20023    @Override
20024    public ComponentName startService(IApplicationThread caller, Intent service,
20025            String resolvedType, boolean requireForeground, String callingPackage, int userId)
20026            throws TransactionTooLargeException {
20027        enforceNotIsolatedCaller("startService");
20028        // Refuse possible leaked file descriptors
20029        if (service != null && service.hasFileDescriptors() == true) {
20030            throw new IllegalArgumentException("File descriptors passed in Intent");
20031        }
20032
20033        if (callingPackage == null) {
20034            throw new IllegalArgumentException("callingPackage cannot be null");
20035        }
20036
20037        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20038                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
20039        synchronized(this) {
20040            final int callingPid = Binder.getCallingPid();
20041            final int callingUid = Binder.getCallingUid();
20042            final long origId = Binder.clearCallingIdentity();
20043            ComponentName res;
20044            try {
20045                res = mServices.startServiceLocked(caller, service,
20046                        resolvedType, callingPid, callingUid,
20047                        requireForeground, callingPackage, userId);
20048            } finally {
20049                Binder.restoreCallingIdentity(origId);
20050            }
20051            return res;
20052        }
20053    }
20054
20055    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
20056            boolean fgRequired, String callingPackage, int userId)
20057            throws TransactionTooLargeException {
20058        synchronized(this) {
20059            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
20060                    "startServiceInPackage: " + service + " type=" + resolvedType);
20061            final long origId = Binder.clearCallingIdentity();
20062            ComponentName res;
20063            try {
20064                res = mServices.startServiceLocked(null, service,
20065                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
20066            } finally {
20067                Binder.restoreCallingIdentity(origId);
20068            }
20069            return res;
20070        }
20071    }
20072
20073    @Override
20074    public int stopService(IApplicationThread caller, Intent service,
20075            String resolvedType, int userId) {
20076        enforceNotIsolatedCaller("stopService");
20077        // Refuse possible leaked file descriptors
20078        if (service != null && service.hasFileDescriptors() == true) {
20079            throw new IllegalArgumentException("File descriptors passed in Intent");
20080        }
20081
20082        synchronized(this) {
20083            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
20084        }
20085    }
20086
20087    @Override
20088    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
20089        enforceNotIsolatedCaller("peekService");
20090        // Refuse possible leaked file descriptors
20091        if (service != null && service.hasFileDescriptors() == true) {
20092            throw new IllegalArgumentException("File descriptors passed in Intent");
20093        }
20094
20095        if (callingPackage == null) {
20096            throw new IllegalArgumentException("callingPackage cannot be null");
20097        }
20098
20099        synchronized(this) {
20100            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
20101        }
20102    }
20103
20104    @Override
20105    public boolean stopServiceToken(ComponentName className, IBinder token,
20106            int startId) {
20107        synchronized(this) {
20108            return mServices.stopServiceTokenLocked(className, token, startId);
20109        }
20110    }
20111
20112    @Override
20113    public void setServiceForeground(ComponentName className, IBinder token,
20114            int id, Notification notification, int flags) {
20115        synchronized(this) {
20116            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
20117        }
20118    }
20119
20120    @Override
20121    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
20122            boolean requireFull, String name, String callerPackage) {
20123        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
20124                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
20125    }
20126
20127    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
20128            String className, int flags) {
20129        boolean result = false;
20130        // For apps that don't have pre-defined UIDs, check for permission
20131        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
20132            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20133                if (ActivityManager.checkUidPermission(
20134                        INTERACT_ACROSS_USERS,
20135                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
20136                    ComponentName comp = new ComponentName(aInfo.packageName, className);
20137                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
20138                            + " requests FLAG_SINGLE_USER, but app does not hold "
20139                            + INTERACT_ACROSS_USERS;
20140                    Slog.w(TAG, msg);
20141                    throw new SecurityException(msg);
20142                }
20143                // Permission passed
20144                result = true;
20145            }
20146        } else if ("system".equals(componentProcessName)) {
20147            result = true;
20148        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
20149            // Phone app and persistent apps are allowed to export singleuser providers.
20150            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
20151                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
20152        }
20153        if (DEBUG_MU) Slog.v(TAG_MU,
20154                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
20155                + Integer.toHexString(flags) + ") = " + result);
20156        return result;
20157    }
20158
20159    /**
20160     * Checks to see if the caller is in the same app as the singleton
20161     * component, or the component is in a special app. It allows special apps
20162     * to export singleton components but prevents exporting singleton
20163     * components for regular apps.
20164     */
20165    boolean isValidSingletonCall(int callingUid, int componentUid) {
20166        int componentAppId = UserHandle.getAppId(componentUid);
20167        return UserHandle.isSameApp(callingUid, componentUid)
20168                || componentAppId == SYSTEM_UID
20169                || componentAppId == PHONE_UID
20170                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
20171                        == PackageManager.PERMISSION_GRANTED;
20172    }
20173
20174    public int bindService(IApplicationThread caller, IBinder token, Intent service,
20175            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
20176            int userId) throws TransactionTooLargeException {
20177        enforceNotIsolatedCaller("bindService");
20178
20179        // Refuse possible leaked file descriptors
20180        if (service != null && service.hasFileDescriptors() == true) {
20181            throw new IllegalArgumentException("File descriptors passed in Intent");
20182        }
20183
20184        if (callingPackage == null) {
20185            throw new IllegalArgumentException("callingPackage cannot be null");
20186        }
20187
20188        synchronized(this) {
20189            return mServices.bindServiceLocked(caller, token, service,
20190                    resolvedType, connection, flags, callingPackage, userId);
20191        }
20192    }
20193
20194    public boolean unbindService(IServiceConnection connection) {
20195        synchronized (this) {
20196            return mServices.unbindServiceLocked(connection);
20197        }
20198    }
20199
20200    public void publishService(IBinder token, Intent intent, IBinder service) {
20201        // Refuse possible leaked file descriptors
20202        if (intent != null && intent.hasFileDescriptors() == true) {
20203            throw new IllegalArgumentException("File descriptors passed in Intent");
20204        }
20205
20206        synchronized(this) {
20207            if (!(token instanceof ServiceRecord)) {
20208                throw new IllegalArgumentException("Invalid service token");
20209            }
20210            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
20211        }
20212    }
20213
20214    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
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            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
20222        }
20223    }
20224
20225    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
20226        synchronized(this) {
20227            if (!(token instanceof ServiceRecord)) {
20228                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
20229                throw new IllegalArgumentException("Invalid service token");
20230            }
20231            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
20232        }
20233    }
20234
20235    // =========================================================
20236    // BACKUP AND RESTORE
20237    // =========================================================
20238
20239    // Cause the target app to be launched if necessary and its backup agent
20240    // instantiated.  The backup agent will invoke backupAgentCreated() on the
20241    // activity manager to announce its creation.
20242    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
20243        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
20244        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
20245
20246        IPackageManager pm = AppGlobals.getPackageManager();
20247        ApplicationInfo app = null;
20248        try {
20249            app = pm.getApplicationInfo(packageName, 0, userId);
20250        } catch (RemoteException e) {
20251            // can't happen; package manager is process-local
20252        }
20253        if (app == null) {
20254            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
20255            return false;
20256        }
20257
20258        int oldBackupUid;
20259        int newBackupUid;
20260
20261        synchronized(this) {
20262            // !!! TODO: currently no check here that we're already bound
20263            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
20264            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20265            synchronized (stats) {
20266                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
20267            }
20268
20269            // Backup agent is now in use, its package can't be stopped.
20270            try {
20271                AppGlobals.getPackageManager().setPackageStoppedState(
20272                        app.packageName, false, UserHandle.getUserId(app.uid));
20273            } catch (RemoteException e) {
20274            } catch (IllegalArgumentException e) {
20275                Slog.w(TAG, "Failed trying to unstop package "
20276                        + app.packageName + ": " + e);
20277            }
20278
20279            BackupRecord r = new BackupRecord(ss, app, backupMode);
20280            ComponentName hostingName =
20281                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
20282                            ? new ComponentName(app.packageName, app.backupAgentName)
20283                            : new ComponentName("android", "FullBackupAgent");
20284            // startProcessLocked() returns existing proc's record if it's already running
20285            ProcessRecord proc = startProcessLocked(app.processName, app,
20286                    false, 0, "backup", hostingName, false, false, false);
20287            if (proc == null) {
20288                Slog.e(TAG, "Unable to start backup agent process " + r);
20289                return false;
20290            }
20291
20292            // If the app is a regular app (uid >= 10000) and not the system server or phone
20293            // process, etc, then mark it as being in full backup so that certain calls to the
20294            // process can be blocked. This is not reset to false anywhere because we kill the
20295            // process after the full backup is done and the ProcessRecord will vaporize anyway.
20296            if (UserHandle.isApp(app.uid) &&
20297                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
20298                proc.inFullBackup = true;
20299            }
20300            r.app = proc;
20301            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20302            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
20303            mBackupTarget = r;
20304            mBackupAppName = app.packageName;
20305
20306            // Try not to kill the process during backup
20307            updateOomAdjLocked(proc, true);
20308
20309            // If the process is already attached, schedule the creation of the backup agent now.
20310            // If it is not yet live, this will be done when it attaches to the framework.
20311            if (proc.thread != null) {
20312                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
20313                try {
20314                    proc.thread.scheduleCreateBackupAgent(app,
20315                            compatibilityInfoForPackageLocked(app), backupMode);
20316                } catch (RemoteException e) {
20317                    // Will time out on the backup manager side
20318                }
20319            } else {
20320                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
20321            }
20322            // Invariants: at this point, the target app process exists and the application
20323            // is either already running or in the process of coming up.  mBackupTarget and
20324            // mBackupAppName describe the app, so that when it binds back to the AM we
20325            // know that it's scheduled for a backup-agent operation.
20326        }
20327
20328        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20329        if (oldBackupUid != -1) {
20330            js.removeBackingUpUid(oldBackupUid);
20331        }
20332        if (newBackupUid != -1) {
20333            js.addBackingUpUid(newBackupUid);
20334        }
20335
20336        return true;
20337    }
20338
20339    @Override
20340    public void clearPendingBackup() {
20341        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
20342        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
20343
20344        synchronized (this) {
20345            mBackupTarget = null;
20346            mBackupAppName = null;
20347        }
20348
20349        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20350        js.clearAllBackingUpUids();
20351    }
20352
20353    // A backup agent has just come up
20354    public void backupAgentCreated(String agentPackageName, IBinder agent) {
20355        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
20356                + " = " + agent);
20357
20358        synchronized(this) {
20359            if (!agentPackageName.equals(mBackupAppName)) {
20360                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
20361                return;
20362            }
20363        }
20364
20365        long oldIdent = Binder.clearCallingIdentity();
20366        try {
20367            IBackupManager bm = IBackupManager.Stub.asInterface(
20368                    ServiceManager.getService(Context.BACKUP_SERVICE));
20369            bm.agentConnected(agentPackageName, agent);
20370        } catch (RemoteException e) {
20371            // can't happen; the backup manager service is local
20372        } catch (Exception e) {
20373            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
20374            e.printStackTrace();
20375        } finally {
20376            Binder.restoreCallingIdentity(oldIdent);
20377        }
20378    }
20379
20380    // done with this agent
20381    public void unbindBackupAgent(ApplicationInfo appInfo) {
20382        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
20383        if (appInfo == null) {
20384            Slog.w(TAG, "unbind backup agent for null app");
20385            return;
20386        }
20387
20388        int oldBackupUid;
20389
20390        synchronized(this) {
20391            try {
20392                if (mBackupAppName == null) {
20393                    Slog.w(TAG, "Unbinding backup agent with no active backup");
20394                    return;
20395                }
20396
20397                if (!mBackupAppName.equals(appInfo.packageName)) {
20398                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
20399                    return;
20400                }
20401
20402                // Not backing this app up any more; reset its OOM adjustment
20403                final ProcessRecord proc = mBackupTarget.app;
20404                updateOomAdjLocked(proc, true);
20405                proc.inFullBackup = false;
20406
20407                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
20408
20409                // If the app crashed during backup, 'thread' will be null here
20410                if (proc.thread != null) {
20411                    try {
20412                        proc.thread.scheduleDestroyBackupAgent(appInfo,
20413                                compatibilityInfoForPackageLocked(appInfo));
20414                    } catch (Exception e) {
20415                        Slog.e(TAG, "Exception when unbinding backup agent:");
20416                        e.printStackTrace();
20417                    }
20418                }
20419            } finally {
20420                mBackupTarget = null;
20421                mBackupAppName = null;
20422            }
20423        }
20424
20425        if (oldBackupUid != -1) {
20426            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
20427            js.removeBackingUpUid(oldBackupUid);
20428        }
20429    }
20430
20431    // =========================================================
20432    // BROADCASTS
20433    // =========================================================
20434
20435    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
20436        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
20437            return false;
20438        }
20439        // Easy case -- we have the app's ProcessRecord.
20440        if (record != null) {
20441            return record.info.isInstantApp();
20442        }
20443        // Otherwise check with PackageManager.
20444        if (callerPackage == null) {
20445            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
20446            throw new IllegalArgumentException("Calling application did not provide package name");
20447        }
20448        mAppOpsService.checkPackage(uid, callerPackage);
20449        try {
20450            IPackageManager pm = AppGlobals.getPackageManager();
20451            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
20452        } catch (RemoteException e) {
20453            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
20454            return true;
20455        }
20456    }
20457
20458    boolean isPendingBroadcastProcessLocked(int pid) {
20459        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
20460                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
20461    }
20462
20463    void skipPendingBroadcastLocked(int pid) {
20464            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
20465            for (BroadcastQueue queue : mBroadcastQueues) {
20466                queue.skipPendingBroadcastLocked(pid);
20467            }
20468    }
20469
20470    // The app just attached; send any pending broadcasts that it should receive
20471    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
20472        boolean didSomething = false;
20473        for (BroadcastQueue queue : mBroadcastQueues) {
20474            didSomething |= queue.sendPendingBroadcastsLocked(app);
20475        }
20476        return didSomething;
20477    }
20478
20479    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
20480            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
20481            int flags) {
20482        enforceNotIsolatedCaller("registerReceiver");
20483        ArrayList<Intent> stickyIntents = null;
20484        ProcessRecord callerApp = null;
20485        final boolean visibleToInstantApps
20486                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
20487        int callingUid;
20488        int callingPid;
20489        boolean instantApp;
20490        synchronized(this) {
20491            if (caller != null) {
20492                callerApp = getRecordForAppLocked(caller);
20493                if (callerApp == null) {
20494                    throw new SecurityException(
20495                            "Unable to find app for caller " + caller
20496                            + " (pid=" + Binder.getCallingPid()
20497                            + ") when registering receiver " + receiver);
20498                }
20499                if (callerApp.info.uid != SYSTEM_UID &&
20500                        !callerApp.pkgList.containsKey(callerPackage) &&
20501                        !"android".equals(callerPackage)) {
20502                    throw new SecurityException("Given caller package " + callerPackage
20503                            + " is not running in process " + callerApp);
20504                }
20505                callingUid = callerApp.info.uid;
20506                callingPid = callerApp.pid;
20507            } else {
20508                callerPackage = null;
20509                callingUid = Binder.getCallingUid();
20510                callingPid = Binder.getCallingPid();
20511            }
20512
20513            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
20514            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20515                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
20516
20517            Iterator<String> actions = filter.actionsIterator();
20518            if (actions == null) {
20519                ArrayList<String> noAction = new ArrayList<String>(1);
20520                noAction.add(null);
20521                actions = noAction.iterator();
20522            }
20523
20524            // Collect stickies of users
20525            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
20526            while (actions.hasNext()) {
20527                String action = actions.next();
20528                for (int id : userIds) {
20529                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
20530                    if (stickies != null) {
20531                        ArrayList<Intent> intents = stickies.get(action);
20532                        if (intents != null) {
20533                            if (stickyIntents == null) {
20534                                stickyIntents = new ArrayList<Intent>();
20535                            }
20536                            stickyIntents.addAll(intents);
20537                        }
20538                    }
20539                }
20540            }
20541        }
20542
20543        ArrayList<Intent> allSticky = null;
20544        if (stickyIntents != null) {
20545            final ContentResolver resolver = mContext.getContentResolver();
20546            // Look for any matching sticky broadcasts...
20547            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
20548                Intent intent = stickyIntents.get(i);
20549                // Don't provided intents that aren't available to instant apps.
20550                if (instantApp &&
20551                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
20552                    continue;
20553                }
20554                // If intent has scheme "content", it will need to acccess
20555                // provider that needs to lock mProviderMap in ActivityThread
20556                // and also it may need to wait application response, so we
20557                // cannot lock ActivityManagerService here.
20558                if (filter.match(resolver, intent, true, TAG) >= 0) {
20559                    if (allSticky == null) {
20560                        allSticky = new ArrayList<Intent>();
20561                    }
20562                    allSticky.add(intent);
20563                }
20564            }
20565        }
20566
20567        // The first sticky in the list is returned directly back to the client.
20568        Intent sticky = allSticky != null ? allSticky.get(0) : null;
20569        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
20570        if (receiver == null) {
20571            return sticky;
20572        }
20573
20574        synchronized (this) {
20575            if (callerApp != null && (callerApp.thread == null
20576                    || callerApp.thread.asBinder() != caller.asBinder())) {
20577                // Original caller already died
20578                return null;
20579            }
20580            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20581            if (rl == null) {
20582                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
20583                        userId, receiver);
20584                if (rl.app != null) {
20585                    rl.app.receivers.add(rl);
20586                } else {
20587                    try {
20588                        receiver.asBinder().linkToDeath(rl, 0);
20589                    } catch (RemoteException e) {
20590                        return sticky;
20591                    }
20592                    rl.linkedToDeath = true;
20593                }
20594                mRegisteredReceivers.put(receiver.asBinder(), rl);
20595            } else if (rl.uid != callingUid) {
20596                throw new IllegalArgumentException(
20597                        "Receiver requested to register for uid " + callingUid
20598                        + " was previously registered for uid " + rl.uid
20599                        + " callerPackage is " + callerPackage);
20600            } else if (rl.pid != callingPid) {
20601                throw new IllegalArgumentException(
20602                        "Receiver requested to register for pid " + callingPid
20603                        + " was previously registered for pid " + rl.pid
20604                        + " callerPackage is " + callerPackage);
20605            } else if (rl.userId != userId) {
20606                throw new IllegalArgumentException(
20607                        "Receiver requested to register for user " + userId
20608                        + " was previously registered for user " + rl.userId
20609                        + " callerPackage is " + callerPackage);
20610            }
20611            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
20612                    permission, callingUid, userId, instantApp, visibleToInstantApps);
20613            rl.add(bf);
20614            if (!bf.debugCheck()) {
20615                Slog.w(TAG, "==> For Dynamic broadcast");
20616            }
20617            mReceiverResolver.addFilter(bf);
20618
20619            // Enqueue broadcasts for all existing stickies that match
20620            // this filter.
20621            if (allSticky != null) {
20622                ArrayList receivers = new ArrayList();
20623                receivers.add(bf);
20624
20625                final int stickyCount = allSticky.size();
20626                for (int i = 0; i < stickyCount; i++) {
20627                    Intent intent = allSticky.get(i);
20628                    BroadcastQueue queue = broadcastQueueForIntent(intent);
20629                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
20630                            null, -1, -1, false, null, null, OP_NONE, null, receivers,
20631                            null, 0, null, null, false, true, true, -1);
20632                    queue.enqueueParallelBroadcastLocked(r);
20633                    queue.scheduleBroadcastsLocked();
20634                }
20635            }
20636
20637            return sticky;
20638        }
20639    }
20640
20641    public void unregisterReceiver(IIntentReceiver receiver) {
20642        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
20643
20644        final long origId = Binder.clearCallingIdentity();
20645        try {
20646            boolean doTrim = false;
20647
20648            synchronized(this) {
20649                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
20650                if (rl != null) {
20651                    final BroadcastRecord r = rl.curBroadcast;
20652                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
20653                        final boolean doNext = r.queue.finishReceiverLocked(
20654                                r, r.resultCode, r.resultData, r.resultExtras,
20655                                r.resultAbort, false);
20656                        if (doNext) {
20657                            doTrim = true;
20658                            r.queue.processNextBroadcast(false);
20659                        }
20660                    }
20661
20662                    if (rl.app != null) {
20663                        rl.app.receivers.remove(rl);
20664                    }
20665                    removeReceiverLocked(rl);
20666                    if (rl.linkedToDeath) {
20667                        rl.linkedToDeath = false;
20668                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
20669                    }
20670                }
20671            }
20672
20673            // If we actually concluded any broadcasts, we might now be able
20674            // to trim the recipients' apps from our working set
20675            if (doTrim) {
20676                trimApplications();
20677                return;
20678            }
20679
20680        } finally {
20681            Binder.restoreCallingIdentity(origId);
20682        }
20683    }
20684
20685    void removeReceiverLocked(ReceiverList rl) {
20686        mRegisteredReceivers.remove(rl.receiver.asBinder());
20687        for (int i = rl.size() - 1; i >= 0; i--) {
20688            mReceiverResolver.removeFilter(rl.get(i));
20689        }
20690    }
20691
20692    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
20693        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20694            ProcessRecord r = mLruProcesses.get(i);
20695            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
20696                try {
20697                    r.thread.dispatchPackageBroadcast(cmd, packages);
20698                } catch (RemoteException ex) {
20699                }
20700            }
20701        }
20702    }
20703
20704    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
20705            int callingUid, int[] users) {
20706        // TODO: come back and remove this assumption to triage all broadcasts
20707        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
20708
20709        List<ResolveInfo> receivers = null;
20710        try {
20711            HashSet<ComponentName> singleUserReceivers = null;
20712            boolean scannedFirstReceivers = false;
20713            for (int user : users) {
20714                // Skip users that have Shell restrictions, with exception of always permitted
20715                // Shell broadcasts
20716                if (callingUid == SHELL_UID
20717                        && mUserController.hasUserRestriction(
20718                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
20719                        && !isPermittedShellBroadcast(intent)) {
20720                    continue;
20721                }
20722                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
20723                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
20724                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
20725                    // If this is not the system user, we need to check for
20726                    // any receivers that should be filtered out.
20727                    for (int i=0; i<newReceivers.size(); i++) {
20728                        ResolveInfo ri = newReceivers.get(i);
20729                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
20730                            newReceivers.remove(i);
20731                            i--;
20732                        }
20733                    }
20734                }
20735                if (newReceivers != null && newReceivers.size() == 0) {
20736                    newReceivers = null;
20737                }
20738                if (receivers == null) {
20739                    receivers = newReceivers;
20740                } else if (newReceivers != null) {
20741                    // We need to concatenate the additional receivers
20742                    // found with what we have do far.  This would be easy,
20743                    // but we also need to de-dup any receivers that are
20744                    // singleUser.
20745                    if (!scannedFirstReceivers) {
20746                        // Collect any single user receivers we had already retrieved.
20747                        scannedFirstReceivers = true;
20748                        for (int i=0; i<receivers.size(); i++) {
20749                            ResolveInfo ri = receivers.get(i);
20750                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20751                                ComponentName cn = new ComponentName(
20752                                        ri.activityInfo.packageName, ri.activityInfo.name);
20753                                if (singleUserReceivers == null) {
20754                                    singleUserReceivers = new HashSet<ComponentName>();
20755                                }
20756                                singleUserReceivers.add(cn);
20757                            }
20758                        }
20759                    }
20760                    // Add the new results to the existing results, tracking
20761                    // and de-dupping single user receivers.
20762                    for (int i=0; i<newReceivers.size(); i++) {
20763                        ResolveInfo ri = newReceivers.get(i);
20764                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
20765                            ComponentName cn = new ComponentName(
20766                                    ri.activityInfo.packageName, ri.activityInfo.name);
20767                            if (singleUserReceivers == null) {
20768                                singleUserReceivers = new HashSet<ComponentName>();
20769                            }
20770                            if (!singleUserReceivers.contains(cn)) {
20771                                singleUserReceivers.add(cn);
20772                                receivers.add(ri);
20773                            }
20774                        } else {
20775                            receivers.add(ri);
20776                        }
20777                    }
20778                }
20779            }
20780        } catch (RemoteException ex) {
20781            // pm is in same process, this will never happen.
20782        }
20783        return receivers;
20784    }
20785
20786    private boolean isPermittedShellBroadcast(Intent intent) {
20787        // remote bugreport should always be allowed to be taken
20788        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
20789    }
20790
20791    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
20792            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
20793        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
20794            // Don't yell about broadcasts sent via shell
20795            return;
20796        }
20797
20798        final String action = intent.getAction();
20799        if (isProtectedBroadcast
20800                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
20801                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
20802                || Intent.ACTION_MEDIA_BUTTON.equals(action)
20803                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
20804                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
20805                || Intent.ACTION_MASTER_CLEAR.equals(action)
20806                || Intent.ACTION_FACTORY_RESET.equals(action)
20807                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
20808                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
20809                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
20810                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
20811                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
20812                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
20813                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
20814            // Broadcast is either protected, or it's a public action that
20815            // we've relaxed, so it's fine for system internals to send.
20816            return;
20817        }
20818
20819        // This broadcast may be a problem...  but there are often system components that
20820        // want to send an internal broadcast to themselves, which is annoying to have to
20821        // explicitly list each action as a protected broadcast, so we will check for that
20822        // one safe case and allow it: an explicit broadcast, only being received by something
20823        // that has protected itself.
20824        if (receivers != null && receivers.size() > 0
20825                && (intent.getPackage() != null || intent.getComponent() != null)) {
20826            boolean allProtected = true;
20827            for (int i = receivers.size()-1; i >= 0; i--) {
20828                Object target = receivers.get(i);
20829                if (target instanceof ResolveInfo) {
20830                    ResolveInfo ri = (ResolveInfo)target;
20831                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
20832                        allProtected = false;
20833                        break;
20834                    }
20835                } else {
20836                    BroadcastFilter bf = (BroadcastFilter)target;
20837                    if (bf.requiredPermission == null) {
20838                        allProtected = false;
20839                        break;
20840                    }
20841                }
20842            }
20843            if (allProtected) {
20844                // All safe!
20845                return;
20846            }
20847        }
20848
20849        // The vast majority of broadcasts sent from system internals
20850        // should be protected to avoid security holes, so yell loudly
20851        // to ensure we examine these cases.
20852        if (callerApp != null) {
20853            Log.wtf(TAG, "Sending non-protected broadcast " + action
20854                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
20855                    new Throwable());
20856        } else {
20857            Log.wtf(TAG, "Sending non-protected broadcast " + action
20858                            + " from system uid " + UserHandle.formatUid(callingUid)
20859                            + " pkg " + callerPackage,
20860                    new Throwable());
20861        }
20862    }
20863
20864    @GuardedBy("this")
20865    final int broadcastIntentLocked(ProcessRecord callerApp,
20866            String callerPackage, Intent intent, String resolvedType,
20867            IIntentReceiver resultTo, int resultCode, String resultData,
20868            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
20869            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
20870        intent = new Intent(intent);
20871
20872        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
20873        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
20874        if (callerInstantApp) {
20875            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20876        }
20877
20878        // By default broadcasts do not go to stopped apps.
20879        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
20880
20881        // If we have not finished booting, don't allow this to launch new processes.
20882        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
20883            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20884        }
20885
20886        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
20887                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
20888                + " ordered=" + ordered + " userid=" + userId);
20889        if ((resultTo != null) && !ordered) {
20890            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
20891        }
20892
20893        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
20894                ALLOW_NON_FULL, "broadcast", callerPackage);
20895
20896        // Make sure that the user who is receiving this broadcast or its parent is running.
20897        // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
20898        if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
20899            if ((callingUid != SYSTEM_UID
20900                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
20901                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
20902                Slog.w(TAG, "Skipping broadcast of " + intent
20903                        + ": user " + userId + " and its parent (if any) are stopped");
20904                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
20905            }
20906        }
20907
20908        BroadcastOptions brOptions = null;
20909        if (bOptions != null) {
20910            brOptions = new BroadcastOptions(bOptions);
20911            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
20912                // See if the caller is allowed to do this.  Note we are checking against
20913                // the actual real caller (not whoever provided the operation as say a
20914                // PendingIntent), because that who is actually supplied the arguments.
20915                if (checkComponentPermission(
20916                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
20917                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
20918                        != PackageManager.PERMISSION_GRANTED) {
20919                    String msg = "Permission Denial: " + intent.getAction()
20920                            + " broadcast from " + callerPackage + " (pid=" + callingPid
20921                            + ", uid=" + callingUid + ")"
20922                            + " requires "
20923                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
20924                    Slog.w(TAG, msg);
20925                    throw new SecurityException(msg);
20926                }
20927            }
20928        }
20929
20930        // Verify that protected broadcasts are only being sent by system code,
20931        // and that system code is only sending protected broadcasts.
20932        final String action = intent.getAction();
20933        final boolean isProtectedBroadcast;
20934        try {
20935            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
20936        } catch (RemoteException e) {
20937            Slog.w(TAG, "Remote exception", e);
20938            return ActivityManager.BROADCAST_SUCCESS;
20939        }
20940
20941        final boolean isCallerSystem;
20942        switch (UserHandle.getAppId(callingUid)) {
20943            case ROOT_UID:
20944            case SYSTEM_UID:
20945            case PHONE_UID:
20946            case BLUETOOTH_UID:
20947            case NFC_UID:
20948            case SE_UID:
20949                isCallerSystem = true;
20950                break;
20951            default:
20952                isCallerSystem = (callerApp != null) && callerApp.persistent;
20953                break;
20954        }
20955
20956        // First line security check before anything else: stop non-system apps from
20957        // sending protected broadcasts.
20958        if (!isCallerSystem) {
20959            if (isProtectedBroadcast) {
20960                String msg = "Permission Denial: not allowed to send broadcast "
20961                        + action + " from pid="
20962                        + callingPid + ", uid=" + callingUid;
20963                Slog.w(TAG, msg);
20964                throw new SecurityException(msg);
20965
20966            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
20967                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
20968                // Special case for compatibility: we don't want apps to send this,
20969                // but historically it has not been protected and apps may be using it
20970                // to poke their own app widget.  So, instead of making it protected,
20971                // just limit it to the caller.
20972                if (callerPackage == null) {
20973                    String msg = "Permission Denial: not allowed to send broadcast "
20974                            + action + " from unknown caller.";
20975                    Slog.w(TAG, msg);
20976                    throw new SecurityException(msg);
20977                } else if (intent.getComponent() != null) {
20978                    // They are good enough to send to an explicit component...  verify
20979                    // it is being sent to the calling app.
20980                    if (!intent.getComponent().getPackageName().equals(
20981                            callerPackage)) {
20982                        String msg = "Permission Denial: not allowed to send broadcast "
20983                                + action + " to "
20984                                + intent.getComponent().getPackageName() + " from "
20985                                + callerPackage;
20986                        Slog.w(TAG, msg);
20987                        throw new SecurityException(msg);
20988                    }
20989                } else {
20990                    // Limit broadcast to their own package.
20991                    intent.setPackage(callerPackage);
20992                }
20993            }
20994        }
20995
20996        if (action != null) {
20997            if (getBackgroundLaunchBroadcasts().contains(action)) {
20998                if (DEBUG_BACKGROUND_CHECK) {
20999                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
21000                }
21001                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
21002            }
21003
21004            switch (action) {
21005                case Intent.ACTION_UID_REMOVED:
21006                case Intent.ACTION_PACKAGE_REMOVED:
21007                case Intent.ACTION_PACKAGE_CHANGED:
21008                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21009                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21010                case Intent.ACTION_PACKAGES_SUSPENDED:
21011                case Intent.ACTION_PACKAGES_UNSUSPENDED:
21012                    // Handle special intents: if this broadcast is from the package
21013                    // manager about a package being removed, we need to remove all of
21014                    // its activities from the history stack.
21015                    if (checkComponentPermission(
21016                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
21017                            callingPid, callingUid, -1, true)
21018                            != PackageManager.PERMISSION_GRANTED) {
21019                        String msg = "Permission Denial: " + intent.getAction()
21020                                + " broadcast from " + callerPackage + " (pid=" + callingPid
21021                                + ", uid=" + callingUid + ")"
21022                                + " requires "
21023                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
21024                        Slog.w(TAG, msg);
21025                        throw new SecurityException(msg);
21026                    }
21027                    switch (action) {
21028                        case Intent.ACTION_UID_REMOVED:
21029                            final int uid = getUidFromIntent(intent);
21030                            if (uid >= 0) {
21031                                mBatteryStatsService.removeUid(uid);
21032                                mAppOpsService.uidRemoved(uid);
21033                            }
21034                            break;
21035                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21036                            // If resources are unavailable just force stop all those packages
21037                            // and flush the attribute cache as well.
21038                            String list[] =
21039                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21040                            if (list != null && list.length > 0) {
21041                                for (int i = 0; i < list.length; i++) {
21042                                    forceStopPackageLocked(list[i], -1, false, true, true,
21043                                            false, false, userId, "storage unmount");
21044                                }
21045                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21046                                sendPackageBroadcastLocked(
21047                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
21048                                        list, userId);
21049                            }
21050                            break;
21051                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21052                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21053                            break;
21054                        case Intent.ACTION_PACKAGE_REMOVED:
21055                        case Intent.ACTION_PACKAGE_CHANGED:
21056                            Uri data = intent.getData();
21057                            String ssp;
21058                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
21059                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
21060                                final boolean replacing =
21061                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21062                                final boolean killProcess =
21063                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
21064                                final boolean fullUninstall = removed && !replacing;
21065                                if (removed) {
21066                                    if (killProcess) {
21067                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
21068                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
21069                                                false, true, true, false, fullUninstall, userId,
21070                                                removed ? "pkg removed" : "pkg changed");
21071                                    }
21072                                    final int cmd = killProcess
21073                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
21074                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
21075                                    sendPackageBroadcastLocked(cmd,
21076                                            new String[] {ssp}, userId);
21077                                    if (fullUninstall) {
21078                                        mAppOpsService.packageRemoved(
21079                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
21080
21081                                        // Remove all permissions granted from/to this package
21082                                        removeUriPermissionsForPackageLocked(ssp, userId, true,
21083                                                false);
21084
21085                                        mRecentTasks.removeTasksByPackageName(ssp, userId);
21086
21087                                        mServices.forceStopPackageLocked(ssp, userId);
21088                                        mAppWarnings.onPackageUninstalled(ssp);
21089                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
21090                                        mBatteryStatsService.notePackageUninstalled(ssp);
21091                                    }
21092                                } else {
21093                                    if (killProcess) {
21094                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
21095                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
21096                                                userId, ProcessList.INVALID_ADJ,
21097                                                false, true, true, false, "change " + ssp);
21098                                    }
21099                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
21100                                            intent.getStringArrayExtra(
21101                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
21102                                }
21103                            }
21104                            break;
21105                        case Intent.ACTION_PACKAGES_SUSPENDED:
21106                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
21107                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
21108                                    intent.getAction());
21109                            final String[] packageNames = intent.getStringArrayExtra(
21110                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
21111                            final int userHandle = intent.getIntExtra(
21112                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
21113
21114                            synchronized(ActivityManagerService.this) {
21115                                mRecentTasks.onPackagesSuspendedChanged(
21116                                        packageNames, suspended, userHandle);
21117                            }
21118                            break;
21119                    }
21120                    break;
21121                case Intent.ACTION_PACKAGE_REPLACED:
21122                {
21123                    final Uri data = intent.getData();
21124                    final String ssp;
21125                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21126                        ApplicationInfo aInfo = null;
21127                        try {
21128                            aInfo = AppGlobals.getPackageManager()
21129                                    .getApplicationInfo(ssp, 0 /*flags*/, userId);
21130                        } catch (RemoteException ignore) {}
21131                        if (aInfo == null) {
21132                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
21133                                    + " ssp=" + ssp + " data=" + data);
21134                            return ActivityManager.BROADCAST_SUCCESS;
21135                        }
21136                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
21137                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
21138                                new String[] {ssp}, userId);
21139                    }
21140                    break;
21141                }
21142                case Intent.ACTION_PACKAGE_ADDED:
21143                {
21144                    // Special case for adding a package: by default turn on compatibility mode.
21145                    Uri data = intent.getData();
21146                    String ssp;
21147                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21148                        final boolean replacing =
21149                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21150                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
21151
21152                        try {
21153                            ApplicationInfo ai = AppGlobals.getPackageManager().
21154                                    getApplicationInfo(ssp, 0, 0);
21155                            mBatteryStatsService.notePackageInstalled(ssp,
21156                                    ai != null ? ai.versionCode : 0);
21157                        } catch (RemoteException e) {
21158                        }
21159                    }
21160                    break;
21161                }
21162                case Intent.ACTION_PACKAGE_DATA_CLEARED:
21163                {
21164                    Uri data = intent.getData();
21165                    String ssp;
21166                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
21167                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
21168                        mAppWarnings.onPackageDataCleared(ssp);
21169                    }
21170                    break;
21171                }
21172                case Intent.ACTION_TIMEZONE_CHANGED:
21173                    // If this is the time zone changed action, queue up a message that will reset
21174                    // the timezone of all currently running processes. This message will get
21175                    // queued up before the broadcast happens.
21176                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
21177                    break;
21178                case Intent.ACTION_TIME_CHANGED:
21179                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
21180                    // the tri-state value it may contain and "unknown".
21181                    // For convenience we re-use the Intent extra values.
21182                    final int NO_EXTRA_VALUE_FOUND = -1;
21183                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
21184                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
21185                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
21186                    // Only send a message if the time preference is available.
21187                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
21188                        Message updateTimePreferenceMsg =
21189                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
21190                                        timeFormatPreferenceMsgValue, 0);
21191                        mHandler.sendMessage(updateTimePreferenceMsg);
21192                    }
21193                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21194                    synchronized (stats) {
21195                        stats.noteCurrentTimeChangedLocked();
21196                    }
21197                    break;
21198                case Intent.ACTION_CLEAR_DNS_CACHE:
21199                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
21200                    break;
21201                case Proxy.PROXY_CHANGE_ACTION:
21202                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
21203                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
21204                    break;
21205                case android.hardware.Camera.ACTION_NEW_PICTURE:
21206                case android.hardware.Camera.ACTION_NEW_VIDEO:
21207                    // In N we just turned these off; in O we are turing them back on partly,
21208                    // only for registered receivers.  This will still address the main problem
21209                    // (a spam of apps waking up when a picture is taken putting significant
21210                    // memory pressure on the system at a bad point), while still allowing apps
21211                    // that are already actively running to know about this happening.
21212                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
21213                    break;
21214                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
21215                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
21216                    break;
21217                case "com.android.launcher.action.INSTALL_SHORTCUT":
21218                    // As of O, we no longer support this broadcasts, even for pre-O apps.
21219                    // Apps should now be using ShortcutManager.pinRequestShortcut().
21220                    Log.w(TAG, "Broadcast " + action
21221                            + " no longer supported. It will not be delivered.");
21222                    return ActivityManager.BROADCAST_SUCCESS;
21223            }
21224
21225            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
21226                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
21227                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
21228                final int uid = getUidFromIntent(intent);
21229                if (uid != -1) {
21230                    final UidRecord uidRec = mActiveUids.get(uid);
21231                    if (uidRec != null) {
21232                        uidRec.updateHasInternetPermission();
21233                    }
21234                }
21235            }
21236        }
21237
21238        // Add to the sticky list if requested.
21239        if (sticky) {
21240            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
21241                    callingPid, callingUid)
21242                    != PackageManager.PERMISSION_GRANTED) {
21243                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
21244                        + callingPid + ", uid=" + callingUid
21245                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21246                Slog.w(TAG, msg);
21247                throw new SecurityException(msg);
21248            }
21249            if (requiredPermissions != null && requiredPermissions.length > 0) {
21250                Slog.w(TAG, "Can't broadcast sticky intent " + intent
21251                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
21252                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
21253            }
21254            if (intent.getComponent() != null) {
21255                throw new SecurityException(
21256                        "Sticky broadcasts can't target a specific component");
21257            }
21258            // We use userId directly here, since the "all" target is maintained
21259            // as a separate set of sticky broadcasts.
21260            if (userId != UserHandle.USER_ALL) {
21261                // But first, if this is not a broadcast to all users, then
21262                // make sure it doesn't conflict with an existing broadcast to
21263                // all users.
21264                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
21265                        UserHandle.USER_ALL);
21266                if (stickies != null) {
21267                    ArrayList<Intent> list = stickies.get(intent.getAction());
21268                    if (list != null) {
21269                        int N = list.size();
21270                        int i;
21271                        for (i=0; i<N; i++) {
21272                            if (intent.filterEquals(list.get(i))) {
21273                                throw new IllegalArgumentException(
21274                                        "Sticky broadcast " + intent + " for user "
21275                                        + userId + " conflicts with existing global broadcast");
21276                            }
21277                        }
21278                    }
21279                }
21280            }
21281            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21282            if (stickies == null) {
21283                stickies = new ArrayMap<>();
21284                mStickyBroadcasts.put(userId, stickies);
21285            }
21286            ArrayList<Intent> list = stickies.get(intent.getAction());
21287            if (list == null) {
21288                list = new ArrayList<>();
21289                stickies.put(intent.getAction(), list);
21290            }
21291            final int stickiesCount = list.size();
21292            int i;
21293            for (i = 0; i < stickiesCount; i++) {
21294                if (intent.filterEquals(list.get(i))) {
21295                    // This sticky already exists, replace it.
21296                    list.set(i, new Intent(intent));
21297                    break;
21298                }
21299            }
21300            if (i >= stickiesCount) {
21301                list.add(new Intent(intent));
21302            }
21303        }
21304
21305        int[] users;
21306        if (userId == UserHandle.USER_ALL) {
21307            // Caller wants broadcast to go to all started users.
21308            users = mUserController.getStartedUserArray();
21309        } else {
21310            // Caller wants broadcast to go to one specific user.
21311            users = new int[] {userId};
21312        }
21313
21314        // Figure out who all will receive this broadcast.
21315        List receivers = null;
21316        List<BroadcastFilter> registeredReceivers = null;
21317        // Need to resolve the intent to interested receivers...
21318        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
21319                 == 0) {
21320            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
21321        }
21322        if (intent.getComponent() == null) {
21323            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
21324                // Query one target user at a time, excluding shell-restricted users
21325                for (int i = 0; i < users.length; i++) {
21326                    if (mUserController.hasUserRestriction(
21327                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
21328                        continue;
21329                    }
21330                    List<BroadcastFilter> registeredReceiversForUser =
21331                            mReceiverResolver.queryIntent(intent,
21332                                    resolvedType, false /*defaultOnly*/, users[i]);
21333                    if (registeredReceivers == null) {
21334                        registeredReceivers = registeredReceiversForUser;
21335                    } else if (registeredReceiversForUser != null) {
21336                        registeredReceivers.addAll(registeredReceiversForUser);
21337                    }
21338                }
21339            } else {
21340                registeredReceivers = mReceiverResolver.queryIntent(intent,
21341                        resolvedType, false /*defaultOnly*/, userId);
21342            }
21343        }
21344
21345        final boolean replacePending =
21346                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
21347
21348        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
21349                + " replacePending=" + replacePending);
21350
21351        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
21352        if (!ordered && NR > 0) {
21353            // If we are not serializing this broadcast, then send the
21354            // registered receivers separately so they don't wait for the
21355            // components to be launched.
21356            if (isCallerSystem) {
21357                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21358                        isProtectedBroadcast, registeredReceivers);
21359            }
21360            final BroadcastQueue queue = broadcastQueueForIntent(intent);
21361            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21362                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21363                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
21364                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
21365            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
21366            final boolean replaced = replacePending
21367                    && (queue.replaceParallelBroadcastLocked(r) != null);
21368            // Note: We assume resultTo is null for non-ordered broadcasts.
21369            if (!replaced) {
21370                queue.enqueueParallelBroadcastLocked(r);
21371                queue.scheduleBroadcastsLocked();
21372            }
21373            registeredReceivers = null;
21374            NR = 0;
21375        }
21376
21377        // Merge into one list.
21378        int ir = 0;
21379        if (receivers != null) {
21380            // A special case for PACKAGE_ADDED: do not allow the package
21381            // being added to see this broadcast.  This prevents them from
21382            // using this as a back door to get run as soon as they are
21383            // installed.  Maybe in the future we want to have a special install
21384            // broadcast or such for apps, but we'd like to deliberately make
21385            // this decision.
21386            String skipPackages[] = null;
21387            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
21388                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
21389                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
21390                Uri data = intent.getData();
21391                if (data != null) {
21392                    String pkgName = data.getSchemeSpecificPart();
21393                    if (pkgName != null) {
21394                        skipPackages = new String[] { pkgName };
21395                    }
21396                }
21397            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
21398                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21399            }
21400            if (skipPackages != null && (skipPackages.length > 0)) {
21401                for (String skipPackage : skipPackages) {
21402                    if (skipPackage != null) {
21403                        int NT = receivers.size();
21404                        for (int it=0; it<NT; it++) {
21405                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
21406                            if (curt.activityInfo.packageName.equals(skipPackage)) {
21407                                receivers.remove(it);
21408                                it--;
21409                                NT--;
21410                            }
21411                        }
21412                    }
21413                }
21414            }
21415
21416            int NT = receivers != null ? receivers.size() : 0;
21417            int it = 0;
21418            ResolveInfo curt = null;
21419            BroadcastFilter curr = null;
21420            while (it < NT && ir < NR) {
21421                if (curt == null) {
21422                    curt = (ResolveInfo)receivers.get(it);
21423                }
21424                if (curr == null) {
21425                    curr = registeredReceivers.get(ir);
21426                }
21427                if (curr.getPriority() >= curt.priority) {
21428                    // Insert this broadcast record into the final list.
21429                    receivers.add(it, curr);
21430                    ir++;
21431                    curr = null;
21432                    it++;
21433                    NT++;
21434                } else {
21435                    // Skip to the next ResolveInfo in the final list.
21436                    it++;
21437                    curt = null;
21438                }
21439            }
21440        }
21441        while (ir < NR) {
21442            if (receivers == null) {
21443                receivers = new ArrayList();
21444            }
21445            receivers.add(registeredReceivers.get(ir));
21446            ir++;
21447        }
21448
21449        if (isCallerSystem) {
21450            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
21451                    isProtectedBroadcast, receivers);
21452        }
21453
21454        if ((receivers != null && receivers.size() > 0)
21455                || resultTo != null) {
21456            BroadcastQueue queue = broadcastQueueForIntent(intent);
21457            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
21458                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
21459                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
21460                    resultData, resultExtras, ordered, sticky, false, userId);
21461
21462            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
21463                    + ": prev had " + queue.mOrderedBroadcasts.size());
21464            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
21465                    "Enqueueing broadcast " + r.intent.getAction());
21466
21467            final BroadcastRecord oldRecord =
21468                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
21469            if (oldRecord != null) {
21470                // Replaced, fire the result-to receiver.
21471                if (oldRecord.resultTo != null) {
21472                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
21473                    try {
21474                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
21475                                oldRecord.intent,
21476                                Activity.RESULT_CANCELED, null, null,
21477                                false, false, oldRecord.userId);
21478                    } catch (RemoteException e) {
21479                        Slog.w(TAG, "Failure ["
21480                                + queue.mQueueName + "] sending broadcast result of "
21481                                + intent, e);
21482
21483                    }
21484                }
21485            } else {
21486                queue.enqueueOrderedBroadcastLocked(r);
21487                queue.scheduleBroadcastsLocked();
21488            }
21489        } else {
21490            // There was nobody interested in the broadcast, but we still want to record
21491            // that it happened.
21492            if (intent.getComponent() == null && intent.getPackage() == null
21493                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21494                // This was an implicit broadcast... let's record it for posterity.
21495                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
21496            }
21497        }
21498
21499        return ActivityManager.BROADCAST_SUCCESS;
21500    }
21501
21502    /**
21503     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
21504     */
21505    private int getUidFromIntent(Intent intent) {
21506        if (intent == null) {
21507            return -1;
21508        }
21509        final Bundle intentExtras = intent.getExtras();
21510        return intent.hasExtra(Intent.EXTRA_UID)
21511                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
21512    }
21513
21514    final void rotateBroadcastStatsIfNeededLocked() {
21515        final long now = SystemClock.elapsedRealtime();
21516        if (mCurBroadcastStats == null ||
21517                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
21518            mLastBroadcastStats = mCurBroadcastStats;
21519            if (mLastBroadcastStats != null) {
21520                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
21521                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
21522            }
21523            mCurBroadcastStats = new BroadcastStats();
21524        }
21525    }
21526
21527    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
21528            int skipCount, long dispatchTime) {
21529        rotateBroadcastStatsIfNeededLocked();
21530        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
21531    }
21532
21533    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
21534        rotateBroadcastStatsIfNeededLocked();
21535        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
21536    }
21537
21538    final Intent verifyBroadcastLocked(Intent intent) {
21539        // Refuse possible leaked file descriptors
21540        if (intent != null && intent.hasFileDescriptors() == true) {
21541            throw new IllegalArgumentException("File descriptors passed in Intent");
21542        }
21543
21544        int flags = intent.getFlags();
21545
21546        if (!mProcessesReady) {
21547            // if the caller really truly claims to know what they're doing, go
21548            // ahead and allow the broadcast without launching any receivers
21549            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
21550                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
21551            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
21552                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
21553                        + " before boot completion");
21554                throw new IllegalStateException("Cannot broadcast before boot completed");
21555            }
21556        }
21557
21558        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
21559            throw new IllegalArgumentException(
21560                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
21561        }
21562
21563        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
21564            switch (Binder.getCallingUid()) {
21565                case ROOT_UID:
21566                case SHELL_UID:
21567                    break;
21568                default:
21569                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
21570                            + Binder.getCallingUid());
21571                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
21572                    break;
21573            }
21574        }
21575
21576        return intent;
21577    }
21578
21579    public final int broadcastIntent(IApplicationThread caller,
21580            Intent intent, String resolvedType, IIntentReceiver resultTo,
21581            int resultCode, String resultData, Bundle resultExtras,
21582            String[] requiredPermissions, int appOp, Bundle bOptions,
21583            boolean serialized, boolean sticky, int userId) {
21584        enforceNotIsolatedCaller("broadcastIntent");
21585        synchronized(this) {
21586            intent = verifyBroadcastLocked(intent);
21587
21588            final ProcessRecord callerApp = getRecordForAppLocked(caller);
21589            final int callingPid = Binder.getCallingPid();
21590            final int callingUid = Binder.getCallingUid();
21591            final long origId = Binder.clearCallingIdentity();
21592            int res = broadcastIntentLocked(callerApp,
21593                    callerApp != null ? callerApp.info.packageName : null,
21594                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
21595                    requiredPermissions, appOp, bOptions, serialized, sticky,
21596                    callingPid, callingUid, userId);
21597            Binder.restoreCallingIdentity(origId);
21598            return res;
21599        }
21600    }
21601
21602
21603    int broadcastIntentInPackage(String packageName, int uid,
21604            Intent intent, String resolvedType, IIntentReceiver resultTo,
21605            int resultCode, String resultData, Bundle resultExtras,
21606            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
21607            int userId) {
21608        synchronized(this) {
21609            intent = verifyBroadcastLocked(intent);
21610
21611            final long origId = Binder.clearCallingIdentity();
21612            String[] requiredPermissions = requiredPermission == null ? null
21613                    : new String[] {requiredPermission};
21614            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
21615                    resultTo, resultCode, resultData, resultExtras,
21616                    requiredPermissions, OP_NONE, bOptions, serialized,
21617                    sticky, -1, uid, userId);
21618            Binder.restoreCallingIdentity(origId);
21619            return res;
21620        }
21621    }
21622
21623    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
21624        // Refuse possible leaked file descriptors
21625        if (intent != null && intent.hasFileDescriptors() == true) {
21626            throw new IllegalArgumentException("File descriptors passed in Intent");
21627        }
21628
21629        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21630                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
21631
21632        synchronized(this) {
21633            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
21634                    != PackageManager.PERMISSION_GRANTED) {
21635                String msg = "Permission Denial: unbroadcastIntent() from pid="
21636                        + Binder.getCallingPid()
21637                        + ", uid=" + Binder.getCallingUid()
21638                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
21639                Slog.w(TAG, msg);
21640                throw new SecurityException(msg);
21641            }
21642            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
21643            if (stickies != null) {
21644                ArrayList<Intent> list = stickies.get(intent.getAction());
21645                if (list != null) {
21646                    int N = list.size();
21647                    int i;
21648                    for (i=0; i<N; i++) {
21649                        if (intent.filterEquals(list.get(i))) {
21650                            list.remove(i);
21651                            break;
21652                        }
21653                    }
21654                    if (list.size() <= 0) {
21655                        stickies.remove(intent.getAction());
21656                    }
21657                }
21658                if (stickies.size() <= 0) {
21659                    mStickyBroadcasts.remove(userId);
21660                }
21661            }
21662        }
21663    }
21664
21665    void backgroundServicesFinishedLocked(int userId) {
21666        for (BroadcastQueue queue : mBroadcastQueues) {
21667            queue.backgroundServicesFinishedLocked(userId);
21668        }
21669    }
21670
21671    public void finishReceiver(IBinder who, int resultCode, String resultData,
21672            Bundle resultExtras, boolean resultAbort, int flags) {
21673        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
21674
21675        // Refuse possible leaked file descriptors
21676        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
21677            throw new IllegalArgumentException("File descriptors passed in Bundle");
21678        }
21679
21680        final long origId = Binder.clearCallingIdentity();
21681        try {
21682            boolean doNext = false;
21683            BroadcastRecord r;
21684
21685            synchronized(this) {
21686                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
21687                        ? mFgBroadcastQueue : mBgBroadcastQueue;
21688                r = queue.getMatchingOrderedReceiver(who);
21689                if (r != null) {
21690                    doNext = r.queue.finishReceiverLocked(r, resultCode,
21691                        resultData, resultExtras, resultAbort, true);
21692                }
21693            }
21694
21695            if (doNext) {
21696                r.queue.processNextBroadcast(false);
21697            }
21698            trimApplications();
21699        } finally {
21700            Binder.restoreCallingIdentity(origId);
21701        }
21702    }
21703
21704    // =========================================================
21705    // INSTRUMENTATION
21706    // =========================================================
21707
21708    public boolean startInstrumentation(ComponentName className,
21709            String profileFile, int flags, Bundle arguments,
21710            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
21711            int userId, String abiOverride) {
21712        enforceNotIsolatedCaller("startInstrumentation");
21713        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21714                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
21715        // Refuse possible leaked file descriptors
21716        if (arguments != null && arguments.hasFileDescriptors()) {
21717            throw new IllegalArgumentException("File descriptors passed in Bundle");
21718        }
21719
21720        synchronized(this) {
21721            InstrumentationInfo ii = null;
21722            ApplicationInfo ai = null;
21723            try {
21724                ii = mContext.getPackageManager().getInstrumentationInfo(
21725                    className, STOCK_PM_FLAGS);
21726                ai = AppGlobals.getPackageManager().getApplicationInfo(
21727                        ii.targetPackage, STOCK_PM_FLAGS, userId);
21728            } catch (PackageManager.NameNotFoundException e) {
21729            } catch (RemoteException e) {
21730            }
21731            if (ii == null) {
21732                reportStartInstrumentationFailureLocked(watcher, className,
21733                        "Unable to find instrumentation info for: " + className);
21734                return false;
21735            }
21736            if (ai == null) {
21737                reportStartInstrumentationFailureLocked(watcher, className,
21738                        "Unable to find instrumentation target package: " + ii.targetPackage);
21739                return false;
21740            }
21741            if (!ai.hasCode()) {
21742                reportStartInstrumentationFailureLocked(watcher, className,
21743                        "Instrumentation target has no code: " + ii.targetPackage);
21744                return false;
21745            }
21746
21747            int match = mContext.getPackageManager().checkSignatures(
21748                    ii.targetPackage, ii.packageName);
21749            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
21750                String msg = "Permission Denial: starting instrumentation "
21751                        + className + " from pid="
21752                        + Binder.getCallingPid()
21753                        + ", uid=" + Binder.getCallingPid()
21754                        + " not allowed because package " + ii.packageName
21755                        + " does not have a signature matching the target "
21756                        + ii.targetPackage;
21757                reportStartInstrumentationFailureLocked(watcher, className, msg);
21758                throw new SecurityException(msg);
21759            }
21760
21761            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
21762            activeInstr.mClass = className;
21763            String defProcess = ai.processName;;
21764            if (ii.targetProcesses == null) {
21765                activeInstr.mTargetProcesses = new String[]{ai.processName};
21766            } else if (ii.targetProcesses.equals("*")) {
21767                activeInstr.mTargetProcesses = new String[0];
21768            } else {
21769                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
21770                defProcess = activeInstr.mTargetProcesses[0];
21771            }
21772            activeInstr.mTargetInfo = ai;
21773            activeInstr.mProfileFile = profileFile;
21774            activeInstr.mArguments = arguments;
21775            activeInstr.mWatcher = watcher;
21776            activeInstr.mUiAutomationConnection = uiAutomationConnection;
21777            activeInstr.mResultClass = className;
21778
21779            final long origId = Binder.clearCallingIdentity();
21780            // Instrumentation can kill and relaunch even persistent processes
21781            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
21782                    "start instr");
21783            // Inform usage stats to make the target package active
21784            if (mUsageStatsService != null) {
21785                mUsageStatsService.reportEvent(ii.targetPackage, userId,
21786                        UsageEvents.Event.SYSTEM_INTERACTION);
21787            }
21788            boolean disableHiddenApiChecks =
21789                    (flags & INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
21790            ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
21791                    abiOverride);
21792            app.instr = activeInstr;
21793            activeInstr.mFinished = false;
21794            activeInstr.mRunningProcesses.add(app);
21795            if (!mActiveInstrumentation.contains(activeInstr)) {
21796                mActiveInstrumentation.add(activeInstr);
21797            }
21798            Binder.restoreCallingIdentity(origId);
21799        }
21800
21801        return true;
21802    }
21803
21804    /**
21805     * Report errors that occur while attempting to start Instrumentation.  Always writes the
21806     * error to the logs, but if somebody is watching, send the report there too.  This enables
21807     * the "am" command to report errors with more information.
21808     *
21809     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
21810     * @param cn The component name of the instrumentation.
21811     * @param report The error report.
21812     */
21813    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
21814            ComponentName cn, String report) {
21815        Slog.w(TAG, report);
21816        if (watcher != null) {
21817            Bundle results = new Bundle();
21818            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
21819            results.putString("Error", report);
21820            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
21821        }
21822    }
21823
21824    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
21825        if (app.instr == null) {
21826            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
21827            return;
21828        }
21829
21830        if (!app.instr.mFinished && results != null) {
21831            if (app.instr.mCurResults == null) {
21832                app.instr.mCurResults = new Bundle(results);
21833            } else {
21834                app.instr.mCurResults.putAll(results);
21835            }
21836        }
21837    }
21838
21839    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
21840        int userId = UserHandle.getCallingUserId();
21841        // Refuse possible leaked file descriptors
21842        if (results != null && results.hasFileDescriptors()) {
21843            throw new IllegalArgumentException("File descriptors passed in Intent");
21844        }
21845
21846        synchronized(this) {
21847            ProcessRecord app = getRecordForAppLocked(target);
21848            if (app == null) {
21849                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
21850                return;
21851            }
21852            final long origId = Binder.clearCallingIdentity();
21853            addInstrumentationResultsLocked(app, results);
21854            Binder.restoreCallingIdentity(origId);
21855        }
21856    }
21857
21858    @GuardedBy("this")
21859    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
21860        if (app.instr == null) {
21861            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
21862            return;
21863        }
21864
21865        if (!app.instr.mFinished) {
21866            if (app.instr.mWatcher != null) {
21867                Bundle finalResults = app.instr.mCurResults;
21868                if (finalResults != null) {
21869                    if (app.instr.mCurResults != null && results != null) {
21870                        finalResults.putAll(results);
21871                    }
21872                } else {
21873                    finalResults = results;
21874                }
21875                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
21876                        app.instr.mClass, resultCode, finalResults);
21877            }
21878
21879            // Can't call out of the system process with a lock held, so post a message.
21880            if (app.instr.mUiAutomationConnection != null) {
21881                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
21882                        app.instr.mUiAutomationConnection).sendToTarget();
21883            }
21884            app.instr.mFinished = true;
21885        }
21886
21887        app.instr.removeProcess(app);
21888        app.instr = null;
21889
21890        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
21891                "finished inst");
21892    }
21893
21894    public void finishInstrumentation(IApplicationThread target,
21895            int resultCode, Bundle results) {
21896        int userId = UserHandle.getCallingUserId();
21897        // Refuse possible leaked file descriptors
21898        if (results != null && results.hasFileDescriptors()) {
21899            throw new IllegalArgumentException("File descriptors passed in Intent");
21900        }
21901
21902        synchronized(this) {
21903            ProcessRecord app = getRecordForAppLocked(target);
21904            if (app == null) {
21905                Slog.w(TAG, "finishInstrumentation: no app for " + target);
21906                return;
21907            }
21908            final long origId = Binder.clearCallingIdentity();
21909            finishInstrumentationLocked(app, resultCode, results);
21910            Binder.restoreCallingIdentity(origId);
21911        }
21912    }
21913
21914    // =========================================================
21915    // CONFIGURATION
21916    // =========================================================
21917
21918    public ConfigurationInfo getDeviceConfigurationInfo() {
21919        ConfigurationInfo config = new ConfigurationInfo();
21920        synchronized (this) {
21921            final Configuration globalConfig = getGlobalConfiguration();
21922            config.reqTouchScreen = globalConfig.touchscreen;
21923            config.reqKeyboardType = globalConfig.keyboard;
21924            config.reqNavigation = globalConfig.navigation;
21925            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
21926                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
21927                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
21928            }
21929            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
21930                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
21931                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
21932            }
21933            config.reqGlEsVersion = GL_ES_VERSION;
21934        }
21935        return config;
21936    }
21937
21938    ActivityStack getFocusedStack() {
21939        return mStackSupervisor.getFocusedStack();
21940    }
21941
21942    @Override
21943    public StackInfo getFocusedStackInfo() throws RemoteException {
21944        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
21945        long ident = Binder.clearCallingIdentity();
21946        try {
21947            synchronized (this) {
21948                ActivityStack focusedStack = getFocusedStack();
21949                if (focusedStack != null) {
21950                    return mStackSupervisor.getStackInfo(focusedStack.mStackId);
21951                }
21952                return null;
21953            }
21954        } finally {
21955            Binder.restoreCallingIdentity(ident);
21956        }
21957    }
21958
21959    public Configuration getConfiguration() {
21960        Configuration ci;
21961        synchronized(this) {
21962            ci = new Configuration(getGlobalConfiguration());
21963            ci.userSetLocale = false;
21964        }
21965        return ci;
21966    }
21967
21968    @Override
21969    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
21970        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
21971        synchronized (this) {
21972            mSuppressResizeConfigChanges = suppress;
21973        }
21974    }
21975
21976    /**
21977     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
21978     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
21979     *       activity and clearing the task at the same time.
21980     */
21981    @Override
21982    // TODO: API should just be about changing windowing modes...
21983    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
21984        enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
21985                "moveTasksToFullscreenStack()");
21986        synchronized (this) {
21987            final long origId = Binder.clearCallingIdentity();
21988            try {
21989                final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
21990                if (stack != null){
21991                    if (!stack.isActivityTypeStandardOrUndefined()) {
21992                        throw new IllegalArgumentException(
21993                                "You can't move tasks from non-standard stacks.");
21994                    }
21995                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
21996                }
21997            } finally {
21998                Binder.restoreCallingIdentity(origId);
21999            }
22000        }
22001    }
22002
22003    @Override
22004    public void updatePersistentConfiguration(Configuration values) {
22005        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
22006        enforceWriteSettingsPermission("updatePersistentConfiguration()");
22007        if (values == null) {
22008            throw new NullPointerException("Configuration must not be null");
22009        }
22010
22011        int userId = UserHandle.getCallingUserId();
22012
22013        synchronized(this) {
22014            updatePersistentConfigurationLocked(values, userId);
22015        }
22016    }
22017
22018    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
22019        final long origId = Binder.clearCallingIdentity();
22020        try {
22021            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
22022        } finally {
22023            Binder.restoreCallingIdentity(origId);
22024        }
22025    }
22026
22027    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
22028        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
22029                FONT_SCALE, 1.0f, userId);
22030
22031        synchronized (this) {
22032            if (getGlobalConfiguration().fontScale == scaleFactor) {
22033                return;
22034            }
22035
22036            final Configuration configuration
22037                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22038            configuration.fontScale = scaleFactor;
22039            updatePersistentConfigurationLocked(configuration, userId);
22040        }
22041    }
22042
22043    private void enforceWriteSettingsPermission(String func) {
22044        int uid = Binder.getCallingUid();
22045        if (uid == ROOT_UID) {
22046            return;
22047        }
22048
22049        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
22050                Settings.getPackageNameForUid(mContext, uid), false)) {
22051            return;
22052        }
22053
22054        String msg = "Permission Denial: " + func + " from pid="
22055                + Binder.getCallingPid()
22056                + ", uid=" + uid
22057                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
22058        Slog.w(TAG, msg);
22059        throw new SecurityException(msg);
22060    }
22061
22062    @Override
22063    public boolean updateConfiguration(Configuration values) {
22064        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
22065
22066        synchronized(this) {
22067            if (values == null && mWindowManager != null) {
22068                // sentinel: fetch the current configuration from the window manager
22069                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
22070            }
22071
22072            if (mWindowManager != null) {
22073                // Update OOM levels based on display size.
22074                mProcessList.applyDisplaySize(mWindowManager);
22075            }
22076
22077            final long origId = Binder.clearCallingIdentity();
22078            try {
22079                if (values != null) {
22080                    Settings.System.clearConfiguration(values);
22081                }
22082                updateConfigurationLocked(values, null, false, false /* persistent */,
22083                        UserHandle.USER_NULL, false /* deferResume */,
22084                        mTmpUpdateConfigurationResult);
22085                return mTmpUpdateConfigurationResult.changes != 0;
22086            } finally {
22087                Binder.restoreCallingIdentity(origId);
22088            }
22089        }
22090    }
22091
22092    void updateUserConfigurationLocked() {
22093        final Configuration configuration = new Configuration(getGlobalConfiguration());
22094        final int currentUserId = mUserController.getCurrentUserId();
22095        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
22096                currentUserId, Settings.System.canWrite(mContext));
22097        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
22098                false /* persistent */, currentUserId, false /* deferResume */);
22099    }
22100
22101    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22102            boolean initLocale) {
22103        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
22104    }
22105
22106    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22107            boolean initLocale, boolean deferResume) {
22108        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
22109        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
22110                UserHandle.USER_NULL, deferResume);
22111    }
22112
22113    // To cache the list of supported system locales
22114    private String[] mSupportedSystemLocales = null;
22115
22116    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22117            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
22118        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
22119                deferResume, null /* result */);
22120    }
22121
22122    /**
22123     * Do either or both things: (1) change the current configuration, and (2)
22124     * make sure the given activity is running with the (now) current
22125     * configuration.  Returns true if the activity has been left running, or
22126     * false if <var>starting</var> is being destroyed to match the new
22127     * configuration.
22128     *
22129     * @param userId is only used when persistent parameter is set to true to persist configuration
22130     *               for that particular user
22131     */
22132    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
22133            boolean initLocale, boolean persistent, int userId, boolean deferResume,
22134            UpdateConfigurationResult result) {
22135        int changes = 0;
22136        boolean kept = true;
22137
22138        if (mWindowManager != null) {
22139            mWindowManager.deferSurfaceLayout();
22140        }
22141        try {
22142            if (values != null) {
22143                changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
22144                        deferResume);
22145            }
22146
22147            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22148        } finally {
22149            if (mWindowManager != null) {
22150                mWindowManager.continueSurfaceLayout();
22151            }
22152        }
22153
22154        if (result != null) {
22155            result.changes = changes;
22156            result.activityRelaunched = !kept;
22157        }
22158        return kept;
22159    }
22160
22161    /**
22162     * Returns true if this configuration change is interesting enough to send an
22163     * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
22164     */
22165    private static boolean isSplitConfigurationChange(int configDiff) {
22166        return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
22167    }
22168
22169    /** Update default (global) configuration and notify listeners about changes. */
22170    private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
22171            boolean persistent, int userId, boolean deferResume) {
22172        mTempConfig.setTo(getGlobalConfiguration());
22173        final int changes = mTempConfig.updateFrom(values);
22174        if (changes == 0) {
22175            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
22176            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
22177            // performDisplayOverrideConfigUpdate in order to send the new display configuration
22178            // (even if there are no actual changes) to unfreeze the window.
22179            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
22180            return 0;
22181        }
22182
22183        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
22184                "Updating global configuration to: " + values);
22185
22186        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
22187
22188        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
22189            final LocaleList locales = values.getLocales();
22190            int bestLocaleIndex = 0;
22191            if (locales.size() > 1) {
22192                if (mSupportedSystemLocales == null) {
22193                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
22194                }
22195                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
22196            }
22197            SystemProperties.set("persist.sys.locale",
22198                    locales.get(bestLocaleIndex).toLanguageTag());
22199            LocaleList.setDefault(locales, bestLocaleIndex);
22200            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
22201                    locales.get(bestLocaleIndex)));
22202        }
22203
22204        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
22205        mTempConfig.seq = mConfigurationSeq;
22206
22207        // Update stored global config and notify everyone about the change.
22208        mStackSupervisor.onConfigurationChanged(mTempConfig);
22209
22210        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
22211        // TODO(multi-display): Update UsageEvents#Event to include displayId.
22212        mUsageStatsService.reportConfigurationChange(mTempConfig,
22213                mUserController.getCurrentUserId());
22214
22215        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
22216        mShowDialogs = shouldShowDialogs(mTempConfig);
22217
22218        AttributeCache ac = AttributeCache.instance();
22219        if (ac != null) {
22220            ac.updateConfiguration(mTempConfig);
22221        }
22222
22223        // Make sure all resources in our process are updated right now, so that anyone who is going
22224        // to retrieve resource values after we return will be sure to get the new ones. This is
22225        // especially important during boot, where the first config change needs to guarantee all
22226        // resources have that config before following boot code is executed.
22227        mSystemThread.applyConfigurationToResources(mTempConfig);
22228
22229        // We need another copy of global config because we're scheduling some calls instead of
22230        // running them in place. We need to be sure that object we send will be handled unchanged.
22231        final Configuration configCopy = new Configuration(mTempConfig);
22232        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
22233            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
22234            msg.obj = configCopy;
22235            msg.arg1 = userId;
22236            mHandler.sendMessage(msg);
22237        }
22238
22239        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22240            ProcessRecord app = mLruProcesses.get(i);
22241            try {
22242                if (app.thread != null) {
22243                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
22244                            + app.processName + " new config " + configCopy);
22245                    mLifecycleManager.scheduleTransaction(app.thread,
22246                            ConfigurationChangeItem.obtain(configCopy));
22247                }
22248            } catch (Exception e) {
22249                Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
22250            }
22251        }
22252
22253        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
22254        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
22255                | Intent.FLAG_RECEIVER_FOREGROUND
22256                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22257        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22258                OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22259                UserHandle.USER_ALL);
22260        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
22261            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
22262            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
22263                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
22264                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
22265            if (initLocale || !mProcessesReady) {
22266                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
22267            }
22268            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
22269                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
22270                    UserHandle.USER_ALL);
22271        }
22272
22273        // Send a broadcast to PackageInstallers if the configuration change is interesting
22274        // for the purposes of installing additional splits.
22275        if (!initLocale && isSplitConfigurationChange(changes)) {
22276            intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
22277            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
22278                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
22279
22280            // Typically only app stores will have this permission.
22281            String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
22282            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
22283                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
22284        }
22285
22286        // Override configuration of the default display duplicates global config, so we need to
22287        // update it also. This will also notify WindowManager about changes.
22288        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
22289                DEFAULT_DISPLAY);
22290
22291        return changes;
22292    }
22293
22294    @Override
22295    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
22296        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
22297
22298        synchronized (this) {
22299            // Check if display is initialized in AM.
22300            if (!mStackSupervisor.isDisplayAdded(displayId)) {
22301                // Call might come when display is not yet added or has already been removed.
22302                if (DEBUG_CONFIGURATION) {
22303                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
22304                            + displayId);
22305                }
22306                return false;
22307            }
22308
22309            if (values == null && mWindowManager != null) {
22310                // sentinel: fetch the current configuration from the window manager
22311                values = mWindowManager.computeNewConfiguration(displayId);
22312            }
22313
22314            if (mWindowManager != null) {
22315                // Update OOM levels based on display size.
22316                mProcessList.applyDisplaySize(mWindowManager);
22317            }
22318
22319            final long origId = Binder.clearCallingIdentity();
22320            try {
22321                if (values != null) {
22322                    Settings.System.clearConfiguration(values);
22323                }
22324                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
22325                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
22326                return mTmpUpdateConfigurationResult.changes != 0;
22327            } finally {
22328                Binder.restoreCallingIdentity(origId);
22329            }
22330        }
22331    }
22332
22333    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
22334            boolean deferResume, int displayId) {
22335        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
22336                displayId, null /* result */);
22337    }
22338
22339    /**
22340     * Updates override configuration specific for the selected display. If no config is provided,
22341     * new one will be computed in WM based on current display info.
22342     */
22343    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
22344            ActivityRecord starting, boolean deferResume, int displayId,
22345            UpdateConfigurationResult result) {
22346        int changes = 0;
22347        boolean kept = true;
22348
22349        if (mWindowManager != null) {
22350            mWindowManager.deferSurfaceLayout();
22351        }
22352        try {
22353            if (values != null) {
22354                if (displayId == DEFAULT_DISPLAY) {
22355                    // Override configuration of the default display duplicates global config, so
22356                    // we're calling global config update instead for default display. It will also
22357                    // apply the correct override config.
22358                    changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
22359                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
22360                } else {
22361                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
22362                }
22363            }
22364
22365            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
22366        } finally {
22367            if (mWindowManager != null) {
22368                mWindowManager.continueSurfaceLayout();
22369            }
22370        }
22371
22372        if (result != null) {
22373            result.changes = changes;
22374            result.activityRelaunched = !kept;
22375        }
22376        return kept;
22377    }
22378
22379    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
22380            int displayId) {
22381        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
22382        final int changes = mTempConfig.updateFrom(values);
22383        if (changes != 0) {
22384            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
22385                    + mTempConfig + " for displayId=" + displayId);
22386            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
22387
22388            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
22389            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
22390                mAppWarnings.onDensityChanged();
22391
22392                killAllBackgroundProcessesExcept(N,
22393                        ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
22394            }
22395        }
22396
22397        // Update the configuration with WM first and check if any of the stacks need to be resized
22398        // due to the configuration change. If so, resize the stacks now and do any relaunches if
22399        // necessary. This way we don't need to relaunch again afterwards in
22400        // ensureActivityConfigurationLocked().
22401        if (mWindowManager != null) {
22402            final int[] resizedStacks =
22403                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
22404            if (resizedStacks != null) {
22405                for (int stackId : resizedStacks) {
22406                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
22407                }
22408            }
22409        }
22410
22411        return changes;
22412    }
22413
22414    /** Applies latest configuration and/or visibility updates if needed. */
22415    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
22416        boolean kept = true;
22417        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
22418        // mainStack is null during startup.
22419        if (mainStack != null) {
22420            if (changes != 0 && starting == null) {
22421                // If the configuration changed, and the caller is not already
22422                // in the process of starting an activity, then find the top
22423                // activity to check if its configuration needs to change.
22424                starting = mainStack.topRunningActivityLocked();
22425            }
22426
22427            if (starting != null) {
22428                kept = starting.ensureActivityConfigurationLocked(changes,
22429                        false /* preserveWindow */);
22430                // And we need to make sure at this point that all other activities
22431                // are made visible with the correct configuration.
22432                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
22433                        !PRESERVE_WINDOWS);
22434            }
22435        }
22436
22437        return kept;
22438    }
22439
22440    /** Helper method that requests bounds from WM and applies them to stack. */
22441    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
22442        final Rect newStackBounds = new Rect();
22443        final ActivityStack stack = mStackSupervisor.getStack(stackId);
22444
22445        // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
22446        if (stack == null) {
22447            final StringWriter writer = new StringWriter();
22448            final PrintWriter printWriter = new PrintWriter(writer);
22449            mStackSupervisor.dumpDisplays(printWriter);
22450            printWriter.flush();
22451
22452            Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
22453        }
22454
22455        stack.getBoundsForNewConfiguration(newStackBounds);
22456        mStackSupervisor.resizeStackLocked(
22457                stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
22458                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
22459                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
22460    }
22461
22462    /**
22463     * Decide based on the configuration whether we should show the ANR,
22464     * crash, etc dialogs.  The idea is that if there is no affordance to
22465     * press the on-screen buttons, or the user experience would be more
22466     * greatly impacted than the crash itself, we shouldn't show the dialog.
22467     *
22468     * A thought: SystemUI might also want to get told about this, the Power
22469     * dialog / global actions also might want different behaviors.
22470     */
22471    private static boolean shouldShowDialogs(Configuration config) {
22472        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
22473                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
22474                                   && config.navigation == Configuration.NAVIGATION_NONAV);
22475        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
22476        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
22477                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
22478                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
22479                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
22480        return inputMethodExists && uiModeSupportsDialogs;
22481    }
22482
22483    @Override
22484    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
22485        synchronized (this) {
22486            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
22487            if (srec != null) {
22488                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
22489            }
22490        }
22491        return false;
22492    }
22493
22494    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
22495            Intent resultData) {
22496
22497        synchronized (this) {
22498            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
22499            if (r != null) {
22500                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
22501            }
22502            return false;
22503        }
22504    }
22505
22506    public int getLaunchedFromUid(IBinder activityToken) {
22507        ActivityRecord srec;
22508        synchronized (this) {
22509            srec = ActivityRecord.forTokenLocked(activityToken);
22510        }
22511        if (srec == null) {
22512            return -1;
22513        }
22514        return srec.launchedFromUid;
22515    }
22516
22517    public String getLaunchedFromPackage(IBinder activityToken) {
22518        ActivityRecord srec;
22519        synchronized (this) {
22520            srec = ActivityRecord.forTokenLocked(activityToken);
22521        }
22522        if (srec == null) {
22523            return null;
22524        }
22525        return srec.launchedFromPackage;
22526    }
22527
22528    // =========================================================
22529    // LIFETIME MANAGEMENT
22530    // =========================================================
22531
22532    // Returns whether the app is receiving broadcast.
22533    // If receiving, fetch all broadcast queues which the app is
22534    // the current [or imminent] receiver on.
22535    private boolean isReceivingBroadcastLocked(ProcessRecord app,
22536            ArraySet<BroadcastQueue> receivingQueues) {
22537        final int N = app.curReceivers.size();
22538        if (N > 0) {
22539            for (int i = 0; i < N; i++) {
22540                receivingQueues.add(app.curReceivers.valueAt(i).queue);
22541            }
22542            return true;
22543        }
22544
22545        // It's not the current receiver, but it might be starting up to become one
22546        for (BroadcastQueue queue : mBroadcastQueues) {
22547            final BroadcastRecord r = queue.mPendingBroadcast;
22548            if (r != null && r.curApp == app) {
22549                // found it; report which queue it's in
22550                receivingQueues.add(queue);
22551            }
22552        }
22553
22554        return !receivingQueues.isEmpty();
22555    }
22556
22557    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
22558            int targetUid, ComponentName targetComponent, String targetProcess) {
22559        if (!mTrackingAssociations) {
22560            return null;
22561        }
22562        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22563                = mAssociations.get(targetUid);
22564        if (components == null) {
22565            components = new ArrayMap<>();
22566            mAssociations.put(targetUid, components);
22567        }
22568        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22569        if (sourceUids == null) {
22570            sourceUids = new SparseArray<>();
22571            components.put(targetComponent, sourceUids);
22572        }
22573        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22574        if (sourceProcesses == null) {
22575            sourceProcesses = new ArrayMap<>();
22576            sourceUids.put(sourceUid, sourceProcesses);
22577        }
22578        Association ass = sourceProcesses.get(sourceProcess);
22579        if (ass == null) {
22580            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
22581                    targetProcess);
22582            sourceProcesses.put(sourceProcess, ass);
22583        }
22584        ass.mCount++;
22585        ass.mNesting++;
22586        if (ass.mNesting == 1) {
22587            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
22588            ass.mLastState = sourceState;
22589        }
22590        return ass;
22591    }
22592
22593    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
22594            ComponentName targetComponent) {
22595        if (!mTrackingAssociations) {
22596            return;
22597        }
22598        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
22599                = mAssociations.get(targetUid);
22600        if (components == null) {
22601            return;
22602        }
22603        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
22604        if (sourceUids == null) {
22605            return;
22606        }
22607        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
22608        if (sourceProcesses == null) {
22609            return;
22610        }
22611        Association ass = sourceProcesses.get(sourceProcess);
22612        if (ass == null || ass.mNesting <= 0) {
22613            return;
22614        }
22615        ass.mNesting--;
22616        if (ass.mNesting == 0) {
22617            long uptime = SystemClock.uptimeMillis();
22618            ass.mTime += uptime - ass.mStartTime;
22619            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22620                    += uptime - ass.mLastStateUptime;
22621            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
22622        }
22623    }
22624
22625    private void noteUidProcessState(final int uid, final int state) {
22626        mBatteryStatsService.noteUidProcessState(uid, state);
22627        if (mTrackingAssociations) {
22628            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
22629                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
22630                        = mAssociations.valueAt(i1);
22631                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
22632                    SparseArray<ArrayMap<String, Association>> sourceUids
22633                            = targetComponents.valueAt(i2);
22634                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
22635                    if (sourceProcesses != null) {
22636                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
22637                            Association ass = sourceProcesses.valueAt(i4);
22638                            if (ass.mNesting >= 1) {
22639                                // currently associated
22640                                long uptime = SystemClock.uptimeMillis();
22641                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
22642                                        += uptime - ass.mLastStateUptime;
22643                                ass.mLastState = state;
22644                                ass.mLastStateUptime = uptime;
22645                            }
22646                        }
22647                    }
22648                }
22649            }
22650        }
22651    }
22652
22653    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
22654            boolean doingAll, long now) {
22655        if (mAdjSeq == app.adjSeq) {
22656            // This adjustment has already been computed.
22657            return app.curRawAdj;
22658        }
22659
22660        if (app.thread == null) {
22661            app.adjSeq = mAdjSeq;
22662            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22663            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22664            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
22665        }
22666
22667        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
22668        app.adjSource = null;
22669        app.adjTarget = null;
22670        app.empty = false;
22671        app.cached = false;
22672
22673        final int activitiesSize = app.activities.size();
22674
22675        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
22676            // The max adjustment doesn't allow this app to be anything
22677            // below foreground, so it is not worth doing work for it.
22678            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
22679            app.adjType = "fixed";
22680            app.adjSeq = mAdjSeq;
22681            app.curRawAdj = app.maxAdj;
22682            app.foregroundActivities = false;
22683            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22684            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
22685            // System processes can do UI, and when they do we want to have
22686            // them trim their memory after the user leaves the UI.  To
22687            // facilitate this, here we need to determine whether or not it
22688            // is currently showing UI.
22689            app.systemNoUi = true;
22690            if (app == TOP_APP) {
22691                app.systemNoUi = false;
22692                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22693                app.adjType = "pers-top-activity";
22694            } else if (app.hasTopUi) {
22695                app.systemNoUi = false;
22696                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22697                app.adjType = "pers-top-ui";
22698            } else if (activitiesSize > 0) {
22699                for (int j = 0; j < activitiesSize; j++) {
22700                    final ActivityRecord r = app.activities.get(j);
22701                    if (r.visible) {
22702                        app.systemNoUi = false;
22703                    }
22704                }
22705            }
22706            if (!app.systemNoUi) {
22707                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
22708            }
22709            return (app.curAdj=app.maxAdj);
22710        }
22711
22712        app.systemNoUi = false;
22713
22714        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
22715
22716        // Determine the importance of the process, starting with most
22717        // important to least, and assign an appropriate OOM adjustment.
22718        int adj;
22719        int schedGroup;
22720        int procState;
22721        boolean foregroundActivities = false;
22722        mTmpBroadcastQueue.clear();
22723        if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
22724            // The last app on the list is the foreground app.
22725            adj = ProcessList.FOREGROUND_APP_ADJ;
22726            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22727            app.adjType = "top-activity";
22728            foregroundActivities = true;
22729            procState = PROCESS_STATE_CUR_TOP;
22730            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
22731        } else if (app.runningRemoteAnimation) {
22732            adj = ProcessList.VISIBLE_APP_ADJ;
22733            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
22734            app.adjType = "running-remote-anim";
22735            procState = PROCESS_STATE_CUR_TOP;
22736            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making running remote anim: " + app);
22737        } else if (app.instr != null) {
22738            // Don't want to kill running instrumentation.
22739            adj = ProcessList.FOREGROUND_APP_ADJ;
22740            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22741            app.adjType = "instrumentation";
22742            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
22743            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
22744        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
22745            // An app that is currently receiving a broadcast also
22746            // counts as being in the foreground for OOM killer purposes.
22747            // It's placed in a sched group based on the nature of the
22748            // broadcast as reflected by which queue it's active in.
22749            adj = ProcessList.FOREGROUND_APP_ADJ;
22750            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
22751                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
22752            app.adjType = "broadcast";
22753            procState = ActivityManager.PROCESS_STATE_RECEIVER;
22754            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
22755        } else if (app.executingServices.size() > 0) {
22756            // An app that is currently executing a service callback also
22757            // counts as being in the foreground.
22758            adj = ProcessList.FOREGROUND_APP_ADJ;
22759            schedGroup = app.execServicesFg ?
22760                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
22761            app.adjType = "exec-service";
22762            procState = ActivityManager.PROCESS_STATE_SERVICE;
22763            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
22764            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
22765        } else if (app == TOP_APP) {
22766            adj = ProcessList.FOREGROUND_APP_ADJ;
22767            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22768            app.adjType = "top-sleeping";
22769            foregroundActivities = true;
22770            procState = PROCESS_STATE_CUR_TOP;
22771            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
22772        } else {
22773            // As far as we know the process is empty.  We may change our mind later.
22774            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22775            // At this point we don't actually know the adjustment.  Use the cached adj
22776            // value that the caller wants us to.
22777            adj = cachedAdj;
22778            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
22779            app.cached = true;
22780            app.empty = true;
22781            app.adjType = "cch-empty";
22782            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
22783        }
22784
22785        // Examine all activities if not already foreground.
22786        if (!foregroundActivities && activitiesSize > 0) {
22787            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
22788            for (int j = 0; j < activitiesSize; j++) {
22789                final ActivityRecord r = app.activities.get(j);
22790                if (r.app != app) {
22791                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
22792                            + " instead of expected " + app);
22793                    if (r.app == null || (r.app.uid == app.uid)) {
22794                        // Only fix things up when they look sane
22795                        r.setProcess(app);
22796                    } else {
22797                        continue;
22798                    }
22799                }
22800                if (r.visible) {
22801                    // App has a visible activity; only upgrade adjustment.
22802                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
22803                        adj = ProcessList.VISIBLE_APP_ADJ;
22804                        app.adjType = "vis-activity";
22805                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
22806                    }
22807                    if (procState > PROCESS_STATE_CUR_TOP) {
22808                        procState = PROCESS_STATE_CUR_TOP;
22809                        app.adjType = "vis-activity";
22810                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
22811                    }
22812                    if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
22813                        schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22814                    }
22815                    app.cached = false;
22816                    app.empty = false;
22817                    foregroundActivities = true;
22818                    final TaskRecord task = r.getTask();
22819                    if (task != null && minLayer > 0) {
22820                        final int layer = task.mLayerRank;
22821                        if (layer >= 0 && minLayer > layer) {
22822                            minLayer = layer;
22823                        }
22824                    }
22825                    break;
22826                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
22827                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22828                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22829                        app.adjType = "pause-activity";
22830                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
22831                    }
22832                    if (procState > PROCESS_STATE_CUR_TOP) {
22833                        procState = PROCESS_STATE_CUR_TOP;
22834                        app.adjType = "pause-activity";
22835                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
22836                    }
22837                    if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) {
22838                        schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22839                    }
22840                    app.cached = false;
22841                    app.empty = false;
22842                    foregroundActivities = true;
22843                } else if (r.state == ActivityState.STOPPING) {
22844                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
22845                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22846                        app.adjType = "stop-activity";
22847                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
22848                    }
22849                    // For the process state, we will at this point consider the
22850                    // process to be cached.  It will be cached either as an activity
22851                    // or empty depending on whether the activity is finishing.  We do
22852                    // this so that we can treat the process as cached for purposes of
22853                    // memory trimming (determing current memory level, trim command to
22854                    // send to process) since there can be an arbitrary number of stopping
22855                    // processes and they should soon all go into the cached state.
22856                    if (!r.finishing) {
22857                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
22858                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
22859                            app.adjType = "stop-activity";
22860                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
22861                        }
22862                    }
22863                    app.cached = false;
22864                    app.empty = false;
22865                    foregroundActivities = true;
22866                } else {
22867                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
22868                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
22869                        app.adjType = "cch-act";
22870                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
22871                    }
22872                }
22873            }
22874            if (adj == ProcessList.VISIBLE_APP_ADJ) {
22875                adj += minLayer;
22876            }
22877        }
22878        if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) {
22879            procState = ActivityManager.PROCESS_STATE_CACHED_RECENT;
22880            app.adjType = "cch-rec";
22881            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached recent: " + app);
22882        }
22883
22884        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
22885                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
22886            if (app.foregroundServices) {
22887                // The user is aware of this app, so make it visible.
22888                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22889                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
22890                app.cached = false;
22891                app.adjType = "fg-service";
22892                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22893                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
22894            } else if (app.hasOverlayUi) {
22895                // The process is display an overlay UI.
22896                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22897                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22898                app.cached = false;
22899                app.adjType = "has-overlay-ui";
22900                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22901                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
22902            }
22903        }
22904
22905        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
22906                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22907            if (app.forcingToImportant != null) {
22908                // This is currently used for toasts...  they are not interactive, and
22909                // we don't want them to cause the app to become fully foreground (and
22910                // thus out of background check), so we yes the best background level we can.
22911                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
22912                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22913                app.cached = false;
22914                app.adjType = "force-imp";
22915                app.adjSource = app.forcingToImportant;
22916                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
22917                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
22918            }
22919        }
22920
22921        if (app == mHeavyWeightProcess) {
22922            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
22923                // We don't want to kill the current heavy-weight process.
22924                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
22925                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22926                app.cached = false;
22927                app.adjType = "heavy";
22928                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
22929            }
22930            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22931                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
22932                app.adjType = "heavy";
22933                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
22934            }
22935        }
22936
22937        if (app == mHomeProcess) {
22938            if (adj > ProcessList.HOME_APP_ADJ) {
22939                // This process is hosting what we currently consider to be the
22940                // home app, so we don't want to let it go into the background.
22941                adj = ProcessList.HOME_APP_ADJ;
22942                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22943                app.cached = false;
22944                app.adjType = "home";
22945                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
22946            }
22947            if (procState > ActivityManager.PROCESS_STATE_HOME) {
22948                procState = ActivityManager.PROCESS_STATE_HOME;
22949                app.adjType = "home";
22950                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
22951            }
22952        }
22953
22954        if (app == mPreviousProcess && app.activities.size() > 0) {
22955            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
22956                // This was the previous process that showed UI to the user.
22957                // We want to try to keep it around more aggressively, to give
22958                // a good experience around switching between two apps.
22959                adj = ProcessList.PREVIOUS_APP_ADJ;
22960                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
22961                app.cached = false;
22962                app.adjType = "previous";
22963                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
22964            }
22965            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
22966                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
22967                app.adjType = "previous";
22968                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
22969            }
22970        }
22971
22972        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
22973                + " reason=" + app.adjType);
22974
22975        // By default, we use the computed adjustment.  It may be changed if
22976        // there are applications dependent on our services or providers, but
22977        // this gives us a baseline and makes sure we don't get into an
22978        // infinite recursion.
22979        app.adjSeq = mAdjSeq;
22980        app.curRawAdj = adj;
22981        app.hasStartedServices = false;
22982
22983        if (mBackupTarget != null && app == mBackupTarget.app) {
22984            // If possible we want to avoid killing apps while they're being backed up
22985            if (adj > ProcessList.BACKUP_APP_ADJ) {
22986                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
22987                adj = ProcessList.BACKUP_APP_ADJ;
22988                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
22989                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
22990                }
22991                app.adjType = "backup";
22992                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
22993                app.cached = false;
22994            }
22995            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
22996                procState = ActivityManager.PROCESS_STATE_BACKUP;
22997                app.adjType = "backup";
22998                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
22999            }
23000        }
23001
23002        boolean mayBeTop = false;
23003        String mayBeTopType = null;
23004        Object mayBeTopSource = null;
23005        Object mayBeTopTarget = null;
23006
23007        for (int is = app.services.size()-1;
23008                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23009                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23010                        || procState > ActivityManager.PROCESS_STATE_TOP);
23011                is--) {
23012            ServiceRecord s = app.services.valueAt(is);
23013            if (s.startRequested) {
23014                app.hasStartedServices = true;
23015                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
23016                    procState = ActivityManager.PROCESS_STATE_SERVICE;
23017                    app.adjType = "started-services";
23018                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
23019                }
23020                if (app.hasShownUi && app != mHomeProcess) {
23021                    // If this process has shown some UI, let it immediately
23022                    // go to the LRU list because it may be pretty heavy with
23023                    // UI stuff.  We'll tag it with a label just to help
23024                    // debug and understand what is going on.
23025                    if (adj > ProcessList.SERVICE_ADJ) {
23026                        app.adjType = "cch-started-ui-services";
23027                    }
23028                } else {
23029                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23030                        // This service has seen some activity within
23031                        // recent memory, so we will keep its process ahead
23032                        // of the background processes.
23033                        if (adj > ProcessList.SERVICE_ADJ) {
23034                            adj = ProcessList.SERVICE_ADJ;
23035                            app.adjType = "started-services";
23036                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
23037                            app.cached = false;
23038                        }
23039                    }
23040                    // If we have let the service slide into the background
23041                    // state, still have some text describing what it is doing
23042                    // even though the service no longer has an impact.
23043                    if (adj > ProcessList.SERVICE_ADJ) {
23044                        app.adjType = "cch-started-services";
23045                    }
23046                }
23047            }
23048
23049            for (int conni = s.connections.size()-1;
23050                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23051                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23052                            || procState > ActivityManager.PROCESS_STATE_TOP);
23053                    conni--) {
23054                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
23055                for (int i = 0;
23056                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
23057                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23058                                || procState > ActivityManager.PROCESS_STATE_TOP);
23059                        i++) {
23060                    // XXX should compute this based on the max of
23061                    // all connected clients.
23062                    ConnectionRecord cr = clist.get(i);
23063                    if (cr.binding.client == app) {
23064                        // Binding to ourself is not interesting.
23065                        continue;
23066                    }
23067
23068                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
23069                        ProcessRecord client = cr.binding.client;
23070                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
23071                                TOP_APP, doingAll, now);
23072                        int clientProcState = client.curProcState;
23073                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23074                            // If the other app is cached for any reason, for purposes here
23075                            // we are going to consider it empty.  The specific cached state
23076                            // doesn't propagate except under certain conditions.
23077                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23078                        }
23079                        String adjType = null;
23080                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
23081                            // Not doing bind OOM management, so treat
23082                            // this guy more like a started service.
23083                            if (app.hasShownUi && app != mHomeProcess) {
23084                                // If this process has shown some UI, let it immediately
23085                                // go to the LRU list because it may be pretty heavy with
23086                                // UI stuff.  We'll tag it with a label just to help
23087                                // debug and understand what is going on.
23088                                if (adj > clientAdj) {
23089                                    adjType = "cch-bound-ui-services";
23090                                }
23091                                app.cached = false;
23092                                clientAdj = adj;
23093                                clientProcState = procState;
23094                            } else {
23095                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
23096                                    // This service has not seen activity within
23097                                    // recent memory, so allow it to drop to the
23098                                    // LRU list if there is no other reason to keep
23099                                    // it around.  We'll also tag it with a label just
23100                                    // to help debug and undertand what is going on.
23101                                    if (adj > clientAdj) {
23102                                        adjType = "cch-bound-services";
23103                                    }
23104                                    clientAdj = adj;
23105                                }
23106                            }
23107                        }
23108                        if (adj > clientAdj) {
23109                            // If this process has recently shown UI, and
23110                            // the process that is binding to it is less
23111                            // important than being visible, then we don't
23112                            // care about the binding as much as we care
23113                            // about letting this process get into the LRU
23114                            // list to be killed and restarted if needed for
23115                            // memory.
23116                            if (app.hasShownUi && app != mHomeProcess
23117                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23118                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
23119                                    adjType = "cch-bound-ui-services";
23120                                }
23121                            } else {
23122                                int newAdj;
23123                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
23124                                        |Context.BIND_IMPORTANT)) != 0) {
23125                                    newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
23126                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
23127                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
23128                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
23129                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23130                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
23131                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
23132                                    newAdj = clientAdj;
23133                                } else {
23134                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
23135                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
23136                                    } else {
23137                                        newAdj = adj;
23138                                    }
23139                                }
23140                                if (!client.cached) {
23141                                    app.cached = false;
23142                                }
23143                                if (adj >  newAdj) {
23144                                    adj = newAdj;
23145                                    adjType = "service";
23146                                }
23147                            }
23148                        }
23149                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
23150                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
23151                            // This will treat important bound services identically to
23152                            // the top app, which may behave differently than generic
23153                            // foreground work.
23154                            if (client.curSchedGroup > schedGroup) {
23155                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23156                                    schedGroup = client.curSchedGroup;
23157                                } else {
23158                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23159                                }
23160                            }
23161                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23162                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23163                                    // Special handling of clients who are in the top state.
23164                                    // We *may* want to consider this process to be in the
23165                                    // top state as well, but only if there is not another
23166                                    // reason for it to be running.  Being on the top is a
23167                                    // special state, meaning you are specifically running
23168                                    // for the current top app.  If the process is already
23169                                    // running in the background for some other reason, it
23170                                    // is more important to continue considering it to be
23171                                    // in the background state.
23172                                    mayBeTop = true;
23173                                    mayBeTopType = "service";
23174                                    mayBeTopSource = cr.binding.client;
23175                                    mayBeTopTarget = s.name;
23176                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23177                                } else {
23178                                    // Special handling for above-top states (persistent
23179                                    // processes).  These should not bring the current process
23180                                    // into the top state, since they are not on top.  Instead
23181                                    // give them the best state after that.
23182                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
23183                                        clientProcState =
23184                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23185                                    } else if (mWakefulness
23186                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
23187                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
23188                                                    != 0) {
23189                                        clientProcState =
23190                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23191                                    } else {
23192                                        clientProcState =
23193                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23194                                    }
23195                                }
23196                            }
23197                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
23198                            if (clientProcState <
23199                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
23200                                clientProcState =
23201                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
23202                            }
23203                        } else {
23204                            if (clientProcState <
23205                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
23206                                clientProcState =
23207                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
23208                            }
23209                        }
23210                        if (procState > clientProcState) {
23211                            procState = clientProcState;
23212                            if (adjType == null) {
23213                                adjType = "service";
23214                            }
23215                        }
23216                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
23217                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
23218                            app.pendingUiClean = true;
23219                        }
23220                        if (adjType != null) {
23221                            app.adjType = adjType;
23222                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23223                                    .REASON_SERVICE_IN_USE;
23224                            app.adjSource = cr.binding.client;
23225                            app.adjSourceProcState = clientProcState;
23226                            app.adjTarget = s.name;
23227                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
23228                                    + ": " + app + ", due to " + cr.binding.client
23229                                    + " adj=" + adj + " procState=" + procState);
23230                        }
23231                    }
23232                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
23233                        app.treatLikeActivity = true;
23234                    }
23235                    final ActivityRecord a = cr.activity;
23236                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
23237                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
23238                            (a.visible || a.state == ActivityState.RESUMED ||
23239                             a.state == ActivityState.PAUSING)) {
23240                            adj = ProcessList.FOREGROUND_APP_ADJ;
23241                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
23242                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
23243                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
23244                                } else {
23245                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23246                                }
23247                            }
23248                            app.cached = false;
23249                            app.adjType = "service";
23250                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23251                                    .REASON_SERVICE_IN_USE;
23252                            app.adjSource = a;
23253                            app.adjSourceProcState = procState;
23254                            app.adjTarget = s.name;
23255                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
23256                                    + app);
23257                        }
23258                    }
23259                }
23260            }
23261        }
23262
23263        for (int provi = app.pubProviders.size()-1;
23264                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23265                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23266                        || procState > ActivityManager.PROCESS_STATE_TOP);
23267                provi--) {
23268            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
23269            for (int i = cpr.connections.size()-1;
23270                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
23271                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
23272                            || procState > ActivityManager.PROCESS_STATE_TOP);
23273                    i--) {
23274                ContentProviderConnection conn = cpr.connections.get(i);
23275                ProcessRecord client = conn.client;
23276                if (client == app) {
23277                    // Being our own client is not interesting.
23278                    continue;
23279                }
23280                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
23281                int clientProcState = client.curProcState;
23282                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
23283                    // If the other app is cached for any reason, for purposes here
23284                    // we are going to consider it empty.
23285                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23286                }
23287                String adjType = null;
23288                if (adj > clientAdj) {
23289                    if (app.hasShownUi && app != mHomeProcess
23290                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
23291                        adjType = "cch-ui-provider";
23292                    } else {
23293                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
23294                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
23295                        adjType = "provider";
23296                    }
23297                    app.cached &= client.cached;
23298                }
23299                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
23300                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
23301                        // Special handling of clients who are in the top state.
23302                        // We *may* want to consider this process to be in the
23303                        // top state as well, but only if there is not another
23304                        // reason for it to be running.  Being on the top is a
23305                        // special state, meaning you are specifically running
23306                        // for the current top app.  If the process is already
23307                        // running in the background for some other reason, it
23308                        // is more important to continue considering it to be
23309                        // in the background state.
23310                        mayBeTop = true;
23311                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
23312                        mayBeTopType = adjType = "provider-top";
23313                        mayBeTopSource = client;
23314                        mayBeTopTarget = cpr.name;
23315                    } else {
23316                        // Special handling for above-top states (persistent
23317                        // processes).  These should not bring the current process
23318                        // into the top state, since they are not on top.  Instead
23319                        // give them the best state after that.
23320                        clientProcState =
23321                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23322                        if (adjType == null) {
23323                            adjType = "provider";
23324                        }
23325                    }
23326                }
23327                if (procState > clientProcState) {
23328                    procState = clientProcState;
23329                }
23330                if (client.curSchedGroup > schedGroup) {
23331                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23332                }
23333                if (adjType != null) {
23334                    app.adjType = adjType;
23335                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
23336                            .REASON_PROVIDER_IN_USE;
23337                    app.adjSource = client;
23338                    app.adjSourceProcState = clientProcState;
23339                    app.adjTarget = cpr.name;
23340                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
23341                            + ": " + app + ", due to " + client
23342                            + " adj=" + adj + " procState=" + procState);
23343                }
23344            }
23345            // If the provider has external (non-framework) process
23346            // dependencies, ensure that its adjustment is at least
23347            // FOREGROUND_APP_ADJ.
23348            if (cpr.hasExternalProcessHandles()) {
23349                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
23350                    adj = ProcessList.FOREGROUND_APP_ADJ;
23351                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23352                    app.cached = false;
23353                    app.adjType = "ext-provider";
23354                    app.adjTarget = cpr.name;
23355                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
23356                }
23357                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
23358                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
23359                }
23360            }
23361        }
23362
23363        if (app.lastProviderTime > 0 &&
23364                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
23365            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
23366                adj = ProcessList.PREVIOUS_APP_ADJ;
23367                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
23368                app.cached = false;
23369                app.adjType = "recent-provider";
23370                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
23371            }
23372            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
23373                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
23374                app.adjType = "recent-provider";
23375                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
23376            }
23377        }
23378
23379        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
23380            // A client of one of our services or providers is in the top state.  We
23381            // *may* want to be in the top state, but not if we are already running in
23382            // the background for some other reason.  For the decision here, we are going
23383            // to pick out a few specific states that we want to remain in when a client
23384            // is top (states that tend to be longer-term) and otherwise allow it to go
23385            // to the top state.
23386            switch (procState) {
23387                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
23388                case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
23389                    // Something else is keeping it at this level, just leave it.
23390                    break;
23391                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
23392                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
23393                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
23394                case ActivityManager.PROCESS_STATE_SERVICE:
23395                    // These all are longer-term states, so pull them up to the top
23396                    // of the background states, but not all the way to the top state.
23397                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
23398                    app.adjType = mayBeTopType;
23399                    app.adjSource = mayBeTopSource;
23400                    app.adjTarget = mayBeTopTarget;
23401                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
23402                            + ": " + app + ", due to " + mayBeTopSource
23403                            + " adj=" + adj + " procState=" + procState);
23404                    break;
23405                default:
23406                    // Otherwise, top is a better choice, so take it.
23407                    procState = ActivityManager.PROCESS_STATE_TOP;
23408                    app.adjType = mayBeTopType;
23409                    app.adjSource = mayBeTopSource;
23410                    app.adjTarget = mayBeTopTarget;
23411                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
23412                            + ": " + app + ", due to " + mayBeTopSource
23413                            + " adj=" + adj + " procState=" + procState);
23414                    break;
23415            }
23416        }
23417
23418        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
23419            if (app.hasClientActivities) {
23420                // This is a cached process, but with client activities.  Mark it so.
23421                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
23422                app.adjType = "cch-client-act";
23423            } else if (app.treatLikeActivity) {
23424                // This is a cached process, but somebody wants us to treat it like it has
23425                // an activity, okay!
23426                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
23427                app.adjType = "cch-as-act";
23428            }
23429        }
23430
23431        if (adj == ProcessList.SERVICE_ADJ) {
23432            if (doingAll) {
23433                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
23434                mNewNumServiceProcs++;
23435                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
23436                if (!app.serviceb) {
23437                    // This service isn't far enough down on the LRU list to
23438                    // normally be a B service, but if we are low on RAM and it
23439                    // is large we want to force it down since we would prefer to
23440                    // keep launcher over it.
23441                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
23442                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
23443                        app.serviceHighRam = true;
23444                        app.serviceb = true;
23445                        //Slog.i(TAG, "ADJ " + app + " high ram!");
23446                    } else {
23447                        mNewNumAServiceProcs++;
23448                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
23449                    }
23450                } else {
23451                    app.serviceHighRam = false;
23452                }
23453            }
23454            if (app.serviceb) {
23455                adj = ProcessList.SERVICE_B_ADJ;
23456            }
23457        }
23458
23459        app.curRawAdj = adj;
23460
23461        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
23462        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
23463        if (adj > app.maxAdj) {
23464            adj = app.maxAdj;
23465            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
23466                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
23467            }
23468        }
23469
23470        // Do final modification to adj.  Everything we do between here and applying
23471        // the final setAdj must be done in this function, because we will also use
23472        // it when computing the final cached adj later.  Note that we don't need to
23473        // worry about this for max adj above, since max adj will always be used to
23474        // keep it out of the cached vaues.
23475        app.curAdj = app.modifyRawOomAdj(adj);
23476        app.curSchedGroup = schedGroup;
23477        app.curProcState = procState;
23478        app.foregroundActivities = foregroundActivities;
23479
23480        return app.curRawAdj;
23481    }
23482
23483    /**
23484     * Record new PSS sample for a process.
23485     */
23486    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
23487            long rss, int statType, long pssDuration, long now) {
23488        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
23489                swapPss * 1024, rss * 1024, statType, procState, pssDuration);
23490        proc.lastPssTime = now;
23491        proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList);
23492        if (DEBUG_PSS) Slog.d(TAG_PSS,
23493                "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
23494                + " state=" + ProcessList.makeProcStateString(procState));
23495        if (proc.initialIdlePss == 0) {
23496            proc.initialIdlePss = pss;
23497        }
23498        proc.lastPss = pss;
23499        proc.lastSwapPss = swapPss;
23500        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
23501            proc.lastCachedPss = pss;
23502            proc.lastCachedSwapPss = swapPss;
23503        }
23504
23505        final SparseArray<Pair<Long, String>> watchUids
23506                = mMemWatchProcesses.getMap().get(proc.processName);
23507        Long check = null;
23508        if (watchUids != null) {
23509            Pair<Long, String> val = watchUids.get(proc.uid);
23510            if (val == null) {
23511                val = watchUids.get(0);
23512            }
23513            if (val != null) {
23514                check = val.first;
23515            }
23516        }
23517        if (check != null) {
23518            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
23519                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23520                if (!isDebuggable) {
23521                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
23522                        isDebuggable = true;
23523                    }
23524                }
23525                if (isDebuggable) {
23526                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
23527                    final ProcessRecord myProc = proc;
23528                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
23529                    mMemWatchDumpProcName = proc.processName;
23530                    mMemWatchDumpFile = heapdumpFile.toString();
23531                    mMemWatchDumpPid = proc.pid;
23532                    mMemWatchDumpUid = proc.uid;
23533                    BackgroundThread.getHandler().post(new Runnable() {
23534                        @Override
23535                        public void run() {
23536                            revokeUriPermission(ActivityThread.currentActivityThread()
23537                                            .getApplicationThread(),
23538                                    null, DumpHeapActivity.JAVA_URI,
23539                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
23540                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
23541                                    UserHandle.myUserId());
23542                            ParcelFileDescriptor fd = null;
23543                            try {
23544                                heapdumpFile.delete();
23545                                fd = ParcelFileDescriptor.open(heapdumpFile,
23546                                        ParcelFileDescriptor.MODE_CREATE |
23547                                                ParcelFileDescriptor.MODE_TRUNCATE |
23548                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
23549                                                ParcelFileDescriptor.MODE_APPEND);
23550                                IApplicationThread thread = myProc.thread;
23551                                if (thread != null) {
23552                                    try {
23553                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
23554                                                "Requesting dump heap from "
23555                                                + myProc + " to " + heapdumpFile);
23556                                        thread.dumpHeap(/* managed= */ true,
23557                                                /* mallocInfo= */ false, /* runGc= */ false,
23558                                                heapdumpFile.toString(), fd);
23559                                    } catch (RemoteException e) {
23560                                    }
23561                                }
23562                            } catch (FileNotFoundException e) {
23563                                e.printStackTrace();
23564                            } finally {
23565                                if (fd != null) {
23566                                    try {
23567                                        fd.close();
23568                                    } catch (IOException e) {
23569                                    }
23570                                }
23571                            }
23572                        }
23573                    });
23574                } else {
23575                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
23576                            + ", but debugging not enabled");
23577                }
23578            }
23579        }
23580    }
23581
23582    /**
23583     * Schedule PSS collection of a process.
23584     */
23585    boolean requestPssLocked(ProcessRecord proc, int procState) {
23586        if (mPendingPssProcesses.contains(proc)) {
23587            return false;
23588        }
23589        if (mPendingPssProcesses.size() == 0) {
23590            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
23591        }
23592        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
23593        proc.pssProcState = procState;
23594        proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE;
23595        mPendingPssProcesses.add(proc);
23596        return true;
23597    }
23598
23599    /**
23600     * Schedule PSS collection of all processes.
23601     */
23602    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
23603        if (!always) {
23604            if (now < (mLastFullPssTime +
23605                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
23606                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
23607                return;
23608            }
23609        }
23610        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs!  memLowered=" + memLowered);
23611        mLastFullPssTime = now;
23612        mFullPssPending = true;
23613        for (int i = mPendingPssProcesses.size() - 1; i >= 0; i--) {
23614            ProcessList.abortNextPssTime(mPendingPssProcesses.get(i).procStateMemTracker);;
23615        }
23616        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
23617        mPendingPssProcesses.clear();
23618        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23619            ProcessRecord app = mLruProcesses.get(i);
23620            if (app.thread == null
23621                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
23622                continue;
23623            }
23624            if (memLowered || (always && now >
23625                            app.lastStateTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
23626                    || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
23627                app.pssProcState = app.setProcState;
23628                app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
23629                        : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
23630                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
23631                        app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
23632                mPendingPssProcesses.add(app);
23633            }
23634        }
23635        if (!mBgHandler.hasMessages(COLLECT_PSS_BG_MSG)) {
23636            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
23637        }
23638    }
23639
23640    public void setTestPssMode(boolean enabled) {
23641        synchronized (this) {
23642            mTestPssMode = enabled;
23643            if (enabled) {
23644                // Whenever we enable the mode, we want to take a snapshot all of current
23645                // process mem use.
23646                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
23647            }
23648        }
23649    }
23650
23651    /**
23652     * Ask a given process to GC right now.
23653     */
23654    final void performAppGcLocked(ProcessRecord app) {
23655        try {
23656            app.lastRequestedGc = SystemClock.uptimeMillis();
23657            if (app.thread != null) {
23658                if (app.reportLowMemory) {
23659                    app.reportLowMemory = false;
23660                    app.thread.scheduleLowMemory();
23661                } else {
23662                    app.thread.processInBackground();
23663                }
23664            }
23665        } catch (Exception e) {
23666            // whatever.
23667        }
23668    }
23669
23670    /**
23671     * Returns true if things are idle enough to perform GCs.
23672     */
23673    private final boolean canGcNowLocked() {
23674        boolean processingBroadcasts = false;
23675        for (BroadcastQueue q : mBroadcastQueues) {
23676            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
23677                processingBroadcasts = true;
23678            }
23679        }
23680        return !processingBroadcasts
23681                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
23682    }
23683
23684    /**
23685     * Perform GCs on all processes that are waiting for it, but only
23686     * if things are idle.
23687     */
23688    final void performAppGcsLocked() {
23689        final int N = mProcessesToGc.size();
23690        if (N <= 0) {
23691            return;
23692        }
23693        if (canGcNowLocked()) {
23694            while (mProcessesToGc.size() > 0) {
23695                ProcessRecord proc = mProcessesToGc.remove(0);
23696                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
23697                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
23698                            <= SystemClock.uptimeMillis()) {
23699                        // To avoid spamming the system, we will GC processes one
23700                        // at a time, waiting a few seconds between each.
23701                        performAppGcLocked(proc);
23702                        scheduleAppGcsLocked();
23703                        return;
23704                    } else {
23705                        // It hasn't been long enough since we last GCed this
23706                        // process...  put it in the list to wait for its time.
23707                        addProcessToGcListLocked(proc);
23708                        break;
23709                    }
23710                }
23711            }
23712
23713            scheduleAppGcsLocked();
23714        }
23715    }
23716
23717    /**
23718     * If all looks good, perform GCs on all processes waiting for them.
23719     */
23720    final void performAppGcsIfAppropriateLocked() {
23721        if (canGcNowLocked()) {
23722            performAppGcsLocked();
23723            return;
23724        }
23725        // Still not idle, wait some more.
23726        scheduleAppGcsLocked();
23727    }
23728
23729    /**
23730     * Schedule the execution of all pending app GCs.
23731     */
23732    final void scheduleAppGcsLocked() {
23733        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
23734
23735        if (mProcessesToGc.size() > 0) {
23736            // Schedule a GC for the time to the next process.
23737            ProcessRecord proc = mProcessesToGc.get(0);
23738            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
23739
23740            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
23741            long now = SystemClock.uptimeMillis();
23742            if (when < (now+mConstants.GC_TIMEOUT)) {
23743                when = now + mConstants.GC_TIMEOUT;
23744            }
23745            mHandler.sendMessageAtTime(msg, when);
23746        }
23747    }
23748
23749    /**
23750     * Add a process to the array of processes waiting to be GCed.  Keeps the
23751     * list in sorted order by the last GC time.  The process can't already be
23752     * on the list.
23753     */
23754    final void addProcessToGcListLocked(ProcessRecord proc) {
23755        boolean added = false;
23756        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
23757            if (mProcessesToGc.get(i).lastRequestedGc <
23758                    proc.lastRequestedGc) {
23759                added = true;
23760                mProcessesToGc.add(i+1, proc);
23761                break;
23762            }
23763        }
23764        if (!added) {
23765            mProcessesToGc.add(0, proc);
23766        }
23767    }
23768
23769    /**
23770     * Set up to ask a process to GC itself.  This will either do it
23771     * immediately, or put it on the list of processes to gc the next
23772     * time things are idle.
23773     */
23774    final void scheduleAppGcLocked(ProcessRecord app) {
23775        long now = SystemClock.uptimeMillis();
23776        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
23777            return;
23778        }
23779        if (!mProcessesToGc.contains(app)) {
23780            addProcessToGcListLocked(app);
23781            scheduleAppGcsLocked();
23782        }
23783    }
23784
23785    final void checkExcessivePowerUsageLocked() {
23786        updateCpuStatsNow();
23787
23788        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
23789        boolean doCpuKills = true;
23790        if (mLastPowerCheckUptime == 0) {
23791            doCpuKills = false;
23792        }
23793        final long curUptime = SystemClock.uptimeMillis();
23794        final long uptimeSince = curUptime - mLastPowerCheckUptime;
23795        mLastPowerCheckUptime = curUptime;
23796        int i = mLruProcesses.size();
23797        while (i > 0) {
23798            i--;
23799            ProcessRecord app = mLruProcesses.get(i);
23800            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
23801                if (app.lastCpuTime <= 0) {
23802                    continue;
23803                }
23804                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
23805                if (DEBUG_POWER) {
23806                    StringBuilder sb = new StringBuilder(128);
23807                    sb.append("CPU for ");
23808                    app.toShortString(sb);
23809                    sb.append(": over ");
23810                    TimeUtils.formatDuration(uptimeSince, sb);
23811                    sb.append(" used ");
23812                    TimeUtils.formatDuration(cputimeUsed, sb);
23813                    sb.append(" (");
23814                    sb.append((cputimeUsed*100)/uptimeSince);
23815                    sb.append("%)");
23816                    Slog.i(TAG_POWER, sb.toString());
23817                }
23818                // If the process has used too much CPU over the last duration, the
23819                // user probably doesn't want this, so kill!
23820                if (doCpuKills && uptimeSince > 0) {
23821                    // What is the limit for this process?
23822                    int cpuLimit;
23823                    long checkDur = curUptime - app.whenUnimportant;
23824                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
23825                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
23826                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
23827                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
23828                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
23829                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
23830                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
23831                    } else {
23832                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
23833                    }
23834                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
23835                        synchronized (stats) {
23836                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
23837                                    uptimeSince, cputimeUsed);
23838                        }
23839                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
23840                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
23841                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
23842                    }
23843                }
23844                app.lastCpuTime = app.curCpuTime;
23845            }
23846        }
23847    }
23848
23849    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
23850            long nowElapsed) {
23851        boolean success = true;
23852
23853        if (app.curRawAdj != app.setRawAdj) {
23854            app.setRawAdj = app.curRawAdj;
23855        }
23856
23857        int changes = 0;
23858
23859        if (app.curAdj != app.setAdj) {
23860            ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
23861            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
23862                String msg = "Set " + app.pid + " " + app.processName + " adj "
23863                        + app.curAdj + ": " + app.adjType;
23864                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23865            }
23866            app.setAdj = app.curAdj;
23867            app.verifiedAdj = ProcessList.INVALID_ADJ;
23868        }
23869
23870        if (app.setSchedGroup != app.curSchedGroup) {
23871            int oldSchedGroup = app.setSchedGroup;
23872            app.setSchedGroup = app.curSchedGroup;
23873            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
23874                String msg = "Setting sched group of " + app.processName
23875                        + " to " + app.curSchedGroup;
23876                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
23877            }
23878            if (app.waitingToKill != null && app.curReceivers.isEmpty()
23879                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
23880                app.kill(app.waitingToKill, true);
23881                success = false;
23882            } else {
23883                int processGroup;
23884                switch (app.curSchedGroup) {
23885                    case ProcessList.SCHED_GROUP_BACKGROUND:
23886                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
23887                        break;
23888                    case ProcessList.SCHED_GROUP_TOP_APP:
23889                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
23890                        processGroup = THREAD_GROUP_TOP_APP;
23891                        break;
23892                    default:
23893                        processGroup = THREAD_GROUP_DEFAULT;
23894                        break;
23895                }
23896                long oldId = Binder.clearCallingIdentity();
23897                try {
23898                    setProcessGroup(app.pid, processGroup);
23899                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
23900                        // do nothing if we already switched to RT
23901                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
23902                            mVrController.onTopProcChangedLocked(app);
23903                            if (mUseFifoUiScheduling) {
23904                                // Switch UI pipeline for app to SCHED_FIFO
23905                                app.savedPriority = Process.getThreadPriority(app.pid);
23906                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
23907                                if (app.renderThreadTid != 0) {
23908                                    scheduleAsFifoPriority(app.renderThreadTid,
23909                                        /* suppressLogs */true);
23910                                    if (DEBUG_OOM_ADJ) {
23911                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
23912                                            app.renderThreadTid + ") to FIFO");
23913                                    }
23914                                } else {
23915                                    if (DEBUG_OOM_ADJ) {
23916                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
23917                                    }
23918                                }
23919                            } else {
23920                                // Boost priority for top app UI and render threads
23921                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
23922                                if (app.renderThreadTid != 0) {
23923                                    try {
23924                                        setThreadPriority(app.renderThreadTid,
23925                                                TOP_APP_PRIORITY_BOOST);
23926                                    } catch (IllegalArgumentException e) {
23927                                        // thread died, ignore
23928                                    }
23929                                }
23930                            }
23931                        }
23932                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
23933                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
23934                        mVrController.onTopProcChangedLocked(app);
23935                        if (mUseFifoUiScheduling) {
23936                            try {
23937                                // Reset UI pipeline to SCHED_OTHER
23938                                setThreadScheduler(app.pid, SCHED_OTHER, 0);
23939                                setThreadPriority(app.pid, app.savedPriority);
23940                                if (app.renderThreadTid != 0) {
23941                                    setThreadScheduler(app.renderThreadTid,
23942                                        SCHED_OTHER, 0);
23943                                    setThreadPriority(app.renderThreadTid, -4);
23944                                }
23945                            } catch (IllegalArgumentException e) {
23946                                Slog.w(TAG,
23947                                        "Failed to set scheduling policy, thread does not exist:\n"
23948                                                + e);
23949                            } catch (SecurityException e) {
23950                                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
23951                            }
23952                        } else {
23953                            // Reset priority for top app UI and render threads
23954                            setThreadPriority(app.pid, 0);
23955                            if (app.renderThreadTid != 0) {
23956                                setThreadPriority(app.renderThreadTid, 0);
23957                            }
23958                        }
23959                    }
23960                } catch (Exception e) {
23961                    if (false) {
23962                        Slog.w(TAG, "Failed setting process group of " + app.pid
23963                                + " to " + app.curSchedGroup);
23964                        Slog.w(TAG, "at location", e);
23965                    }
23966                } finally {
23967                    Binder.restoreCallingIdentity(oldId);
23968                }
23969            }
23970        }
23971        if (app.repForegroundActivities != app.foregroundActivities) {
23972            app.repForegroundActivities = app.foregroundActivities;
23973            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
23974        }
23975        if (app.repProcState != app.curProcState) {
23976            app.repProcState = app.curProcState;
23977            if (app.thread != null) {
23978                try {
23979                    if (false) {
23980                        //RuntimeException h = new RuntimeException("here");
23981                        Slog.i(TAG, "Sending new process state " + app.repProcState
23982                                + " to " + app /*, h*/);
23983                    }
23984                    app.thread.setProcessState(app.repProcState);
23985                } catch (RemoteException e) {
23986                }
23987            }
23988        }
23989        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
23990                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
23991            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
23992                // Experimental code to more aggressively collect pss while
23993                // running test...  the problem is that this tends to collect
23994                // the data right when a process is transitioning between process
23995                // states, which will tend to give noisy data.
23996                long start = SystemClock.uptimeMillis();
23997                long startTime = SystemClock.currentThreadTimeMillis();
23998                long pss = Debug.getPss(app.pid, mTmpLong, null);
23999                long endTime = SystemClock.currentThreadTimeMillis();
24000                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1],
24001                        mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now);
24002                mPendingPssProcesses.remove(app);
24003                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
24004                        + " to " + app.curProcState + ": "
24005                        + (SystemClock.uptimeMillis()-start) + "ms");
24006            }
24007            app.lastStateTime = now;
24008            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24009                    app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24010            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
24011                    + ProcessList.makeProcStateString(app.setProcState) + " to "
24012                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
24013                    + (app.nextPssTime-now) + ": " + app);
24014        } else {
24015            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
24016                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
24017                    mTestPssMode)))) {
24018                if (requestPssLocked(app, app.setProcState)) {
24019                    app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
24020                            app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
24021                }
24022            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
24023                    "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
24024        }
24025        if (app.setProcState != app.curProcState) {
24026            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
24027                String msg = "Proc state change of " + app.processName
24028                        + " to " + app.curProcState;
24029                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
24030            }
24031            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
24032            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
24033            if (setImportant && !curImportant) {
24034                // This app is no longer something we consider important enough to allow to
24035                // use arbitrary amounts of battery power.  Note
24036                // its current CPU time to later know to kill it if
24037                // it is not behaving well.
24038                app.whenUnimportant = now;
24039                app.lastCpuTime = 0;
24040            }
24041            // Inform UsageStats of important process state change
24042            // Must be called before updating setProcState
24043            maybeUpdateUsageStatsLocked(app, nowElapsed);
24044
24045            app.setProcState = app.curProcState;
24046            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
24047                app.notCachedSinceIdle = false;
24048            }
24049            if (!doingAll) {
24050                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
24051            } else {
24052                app.procStateChanged = true;
24053            }
24054        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
24055                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
24056            // For apps that sit around for a long time in the interactive state, we need
24057            // to report this at least once a day so they don't go idle.
24058            maybeUpdateUsageStatsLocked(app, nowElapsed);
24059        }
24060
24061        if (changes != 0) {
24062            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24063                    "Changes in " + app + ": " + changes);
24064            int i = mPendingProcessChanges.size()-1;
24065            ProcessChangeItem item = null;
24066            while (i >= 0) {
24067                item = mPendingProcessChanges.get(i);
24068                if (item.pid == app.pid) {
24069                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24070                            "Re-using existing item: " + item);
24071                    break;
24072                }
24073                i--;
24074            }
24075            if (i < 0) {
24076                // No existing item in pending changes; need a new one.
24077                final int NA = mAvailProcessChanges.size();
24078                if (NA > 0) {
24079                    item = mAvailProcessChanges.remove(NA-1);
24080                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24081                            "Retrieving available item: " + item);
24082                } else {
24083                    item = new ProcessChangeItem();
24084                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24085                            "Allocating new item: " + item);
24086                }
24087                item.changes = 0;
24088                item.pid = app.pid;
24089                item.uid = app.info.uid;
24090                if (mPendingProcessChanges.size() == 0) {
24091                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24092                            "*** Enqueueing dispatch processes changed!");
24093                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
24094                }
24095                mPendingProcessChanges.add(item);
24096            }
24097            item.changes |= changes;
24098            item.foregroundActivities = app.repForegroundActivities;
24099            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
24100                    "Item " + Integer.toHexString(System.identityHashCode(item))
24101                    + " " + app.toShortString() + ": changes=" + item.changes
24102                    + " foreground=" + item.foregroundActivities
24103                    + " type=" + app.adjType + " source=" + app.adjSource
24104                    + " target=" + app.adjTarget);
24105        }
24106
24107        return success;
24108    }
24109
24110    private boolean isEphemeralLocked(int uid) {
24111        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
24112        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
24113            return false;
24114        }
24115        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
24116                packages[0]);
24117    }
24118
24119    @VisibleForTesting
24120    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
24121        final UidRecord.ChangeItem pendingChange;
24122        if (uidRec == null || uidRec.pendingChange == null) {
24123            if (mPendingUidChanges.size() == 0) {
24124                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24125                        "*** Enqueueing dispatch uid changed!");
24126                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
24127            }
24128            final int NA = mAvailUidChanges.size();
24129            if (NA > 0) {
24130                pendingChange = mAvailUidChanges.remove(NA-1);
24131                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24132                        "Retrieving available item: " + pendingChange);
24133            } else {
24134                pendingChange = new UidRecord.ChangeItem();
24135                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24136                        "Allocating new item: " + pendingChange);
24137            }
24138            if (uidRec != null) {
24139                uidRec.pendingChange = pendingChange;
24140                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
24141                    // If this uid is going away, and we haven't yet reported it is gone,
24142                    // then do so now.
24143                    change |= UidRecord.CHANGE_IDLE;
24144                }
24145            } else if (uid < 0) {
24146                throw new IllegalArgumentException("No UidRecord or uid");
24147            }
24148            pendingChange.uidRecord = uidRec;
24149            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
24150            mPendingUidChanges.add(pendingChange);
24151        } else {
24152            pendingChange = uidRec.pendingChange;
24153            // If there is no change in idle or active state, then keep whatever was pending.
24154            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
24155                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
24156                        | UidRecord.CHANGE_ACTIVE));
24157            }
24158            // If there is no change in cached or uncached state, then keep whatever was pending.
24159            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
24160                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
24161                        | UidRecord.CHANGE_UNCACHED));
24162            }
24163            // If this is a report of the UID being gone, then we shouldn't keep any previous
24164            // report of it being active or cached.  (That is, a gone uid is never active,
24165            // and never cached.)
24166            if ((change & UidRecord.CHANGE_GONE) != 0) {
24167                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
24168                if (!uidRec.idle) {
24169                    // If this uid is going away, and we haven't yet reported it is gone,
24170                    // then do so now.
24171                    change |= UidRecord.CHANGE_IDLE;
24172                }
24173            }
24174        }
24175        pendingChange.change = change;
24176        pendingChange.processState = uidRec != null
24177                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
24178        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
24179        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
24180        if (uidRec != null) {
24181            uidRec.lastReportedChange = change;
24182            uidRec.updateLastDispatchedProcStateSeq(change);
24183        }
24184
24185        // Directly update the power manager, since we sit on top of it and it is critical
24186        // it be kept in sync (so wake locks will be held as soon as appropriate).
24187        if (mLocalPowerManager != null) {
24188            // TO DO: dispatch cached/uncached changes here, so we don't need to report
24189            // all proc state changes.
24190            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
24191                mLocalPowerManager.uidActive(pendingChange.uid);
24192            }
24193            if ((change & UidRecord.CHANGE_IDLE) != 0) {
24194                mLocalPowerManager.uidIdle(pendingChange.uid);
24195            }
24196            if ((change & UidRecord.CHANGE_GONE) != 0) {
24197                mLocalPowerManager.uidGone(pendingChange.uid);
24198            } else {
24199                mLocalPowerManager.updateUidProcState(pendingChange.uid,
24200                        pendingChange.processState);
24201            }
24202        }
24203    }
24204
24205    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
24206            String authority) {
24207        if (app == null) return;
24208        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
24209            UserState userState = mUserController.getStartedUserState(app.userId);
24210            if (userState == null) return;
24211            final long now = SystemClock.elapsedRealtime();
24212            Long lastReported = userState.mProviderLastReportedFg.get(authority);
24213            if (lastReported == null || lastReported < now - 60 * 1000L) {
24214                if (mSystemReady) {
24215                    // Cannot touch the user stats if not system ready
24216                    mUsageStatsService.reportContentProviderUsage(
24217                            authority, providerPkgName, app.userId);
24218                }
24219                userState.mProviderLastReportedFg.put(authority, now);
24220            }
24221        }
24222    }
24223
24224    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
24225        if (DEBUG_USAGE_STATS) {
24226            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
24227                    + "] state changes: old = " + app.setProcState + ", new = "
24228                    + app.curProcState);
24229        }
24230        if (mUsageStatsService == null) {
24231            return;
24232        }
24233        boolean isInteraction;
24234        // To avoid some abuse patterns, we are going to be careful about what we consider
24235        // to be an app interaction.  Being the top activity doesn't count while the display
24236        // is sleeping, nor do short foreground services.
24237        if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
24238            isInteraction = true;
24239            app.fgInteractionTime = 0;
24240        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
24241            if (app.fgInteractionTime == 0) {
24242                app.fgInteractionTime = nowElapsed;
24243                isInteraction = false;
24244            } else {
24245                isInteraction = nowElapsed > app.fgInteractionTime
24246                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
24247            }
24248        } else {
24249            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
24250            app.fgInteractionTime = 0;
24251        }
24252        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
24253                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
24254            app.interactionEventTime = nowElapsed;
24255            String[] packages = app.getPackageList();
24256            if (packages != null) {
24257                for (int i = 0; i < packages.length; i++) {
24258                    mUsageStatsService.reportEvent(packages[i], app.userId,
24259                            UsageEvents.Event.SYSTEM_INTERACTION);
24260                }
24261            }
24262        }
24263        app.reportedInteraction = isInteraction;
24264        if (!isInteraction) {
24265            app.interactionEventTime = 0;
24266        }
24267    }
24268
24269    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
24270        if (proc.thread != null) {
24271            if (proc.baseProcessTracker != null) {
24272                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
24273            }
24274        }
24275    }
24276
24277    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
24278            ProcessRecord TOP_APP, boolean doingAll, long now) {
24279        if (app.thread == null) {
24280            return false;
24281        }
24282
24283        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
24284
24285        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
24286    }
24287
24288    @GuardedBy("this")
24289    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
24290            boolean oomAdj) {
24291        if (isForeground != proc.foregroundServices) {
24292            proc.foregroundServices = isForeground;
24293            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
24294                    proc.info.uid);
24295            if (isForeground) {
24296                if (curProcs == null) {
24297                    curProcs = new ArrayList<ProcessRecord>();
24298                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
24299                }
24300                if (!curProcs.contains(proc)) {
24301                    curProcs.add(proc);
24302                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
24303                            proc.info.packageName, proc.info.uid);
24304                }
24305            } else {
24306                if (curProcs != null) {
24307                    if (curProcs.remove(proc)) {
24308                        mBatteryStatsService.noteEvent(
24309                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
24310                                proc.info.packageName, proc.info.uid);
24311                        if (curProcs.size() <= 0) {
24312                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
24313                        }
24314                    }
24315                }
24316            }
24317            if (oomAdj) {
24318                updateOomAdjLocked();
24319            }
24320        }
24321    }
24322
24323    private final ActivityRecord resumedAppLocked() {
24324        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
24325        String pkg;
24326        int uid;
24327        if (act != null) {
24328            pkg = act.packageName;
24329            uid = act.info.applicationInfo.uid;
24330        } else {
24331            pkg = null;
24332            uid = -1;
24333        }
24334        // Has the UID or resumed package name changed?
24335        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
24336                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
24337            if (mCurResumedPackage != null) {
24338                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
24339                        mCurResumedPackage, mCurResumedUid);
24340            }
24341            mCurResumedPackage = pkg;
24342            mCurResumedUid = uid;
24343            if (mCurResumedPackage != null) {
24344                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
24345                        mCurResumedPackage, mCurResumedUid);
24346            }
24347        }
24348        return act;
24349    }
24350
24351    /**
24352     * Update OomAdj for a specific process.
24353     * @param app The process to update
24354     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
24355     *                  if necessary, or skip.
24356     * @return whether updateOomAdjLocked(app) was successful.
24357     */
24358    @GuardedBy("this")
24359    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
24360        final ActivityRecord TOP_ACT = resumedAppLocked();
24361        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24362        final boolean wasCached = app.cached;
24363
24364        mAdjSeq++;
24365
24366        // This is the desired cached adjusment we want to tell it to use.
24367        // If our app is currently cached, we know it, and that is it.  Otherwise,
24368        // we don't know it yet, and it needs to now be cached we will then
24369        // need to do a complete oom adj.
24370        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
24371                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
24372        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
24373                SystemClock.uptimeMillis());
24374        if (oomAdjAll
24375                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
24376            // Changed to/from cached state, so apps after it in the LRU
24377            // list may also be changed.
24378            updateOomAdjLocked();
24379        }
24380        return success;
24381    }
24382
24383    @GuardedBy("this")
24384    final void updateOomAdjLocked() {
24385        final ActivityRecord TOP_ACT = resumedAppLocked();
24386        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
24387        final long now = SystemClock.uptimeMillis();
24388        final long nowElapsed = SystemClock.elapsedRealtime();
24389        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
24390        final int N = mLruProcesses.size();
24391
24392        if (false) {
24393            RuntimeException e = new RuntimeException();
24394            e.fillInStackTrace();
24395            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
24396        }
24397
24398        // Reset state in all uid records.
24399        for (int i=mActiveUids.size()-1; i>=0; i--) {
24400            final UidRecord uidRec = mActiveUids.valueAt(i);
24401            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24402                    "Starting update of " + uidRec);
24403            uidRec.reset();
24404        }
24405
24406        mStackSupervisor.rankTaskLayersIfNeeded();
24407
24408        mAdjSeq++;
24409        mNewNumServiceProcs = 0;
24410        mNewNumAServiceProcs = 0;
24411
24412        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
24413        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
24414
24415        // Let's determine how many processes we have running vs.
24416        // how many slots we have for background processes; we may want
24417        // to put multiple processes in a slot of there are enough of
24418        // them.
24419        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
24420                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
24421        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
24422        if (numEmptyProcs > cachedProcessLimit) {
24423            // If there are more empty processes than our limit on cached
24424            // processes, then use the cached process limit for the factor.
24425            // This ensures that the really old empty processes get pushed
24426            // down to the bottom, so if we are running low on memory we will
24427            // have a better chance at keeping around more cached processes
24428            // instead of a gazillion empty processes.
24429            numEmptyProcs = cachedProcessLimit;
24430        }
24431        int emptyFactor = numEmptyProcs/numSlots;
24432        if (emptyFactor < 1) emptyFactor = 1;
24433        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
24434        if (cachedFactor < 1) cachedFactor = 1;
24435        int stepCached = 0;
24436        int stepEmpty = 0;
24437        int numCached = 0;
24438        int numEmpty = 0;
24439        int numTrimming = 0;
24440
24441        mNumNonCachedProcs = 0;
24442        mNumCachedHiddenProcs = 0;
24443
24444        // First update the OOM adjustment for each of the
24445        // application processes based on their current state.
24446        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
24447        int nextCachedAdj = curCachedAdj+1;
24448        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
24449        int nextEmptyAdj = curEmptyAdj+2;
24450        for (int i=N-1; i>=0; i--) {
24451            ProcessRecord app = mLruProcesses.get(i);
24452            if (!app.killedByAm && app.thread != null) {
24453                app.procStateChanged = false;
24454                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
24455
24456                // If we haven't yet assigned the final cached adj
24457                // to the process, do that now.
24458                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
24459                    switch (app.curProcState) {
24460                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
24461                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
24462                        case ActivityManager.PROCESS_STATE_CACHED_RECENT:
24463                            // This process is a cached process holding activities...
24464                            // assign it the next cached value for that type, and then
24465                            // step that cached level.
24466                            app.curRawAdj = curCachedAdj;
24467                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
24468                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
24469                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
24470                                    + ")");
24471                            if (curCachedAdj != nextCachedAdj) {
24472                                stepCached++;
24473                                if (stepCached >= cachedFactor) {
24474                                    stepCached = 0;
24475                                    curCachedAdj = nextCachedAdj;
24476                                    nextCachedAdj += 2;
24477                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
24478                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
24479                                    }
24480                                }
24481                            }
24482                            break;
24483                        default:
24484                            // For everything else, assign next empty cached process
24485                            // level and bump that up.  Note that this means that
24486                            // long-running services that have dropped down to the
24487                            // cached level will be treated as empty (since their process
24488                            // state is still as a service), which is what we want.
24489                            app.curRawAdj = curEmptyAdj;
24490                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
24491                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
24492                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
24493                                    + ")");
24494                            if (curEmptyAdj != nextEmptyAdj) {
24495                                stepEmpty++;
24496                                if (stepEmpty >= emptyFactor) {
24497                                    stepEmpty = 0;
24498                                    curEmptyAdj = nextEmptyAdj;
24499                                    nextEmptyAdj += 2;
24500                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
24501                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
24502                                    }
24503                                }
24504                            }
24505                            break;
24506                    }
24507                }
24508
24509                applyOomAdjLocked(app, true, now, nowElapsed);
24510
24511                // Count the number of process types.
24512                switch (app.curProcState) {
24513                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
24514                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
24515                        mNumCachedHiddenProcs++;
24516                        numCached++;
24517                        if (numCached > cachedProcessLimit) {
24518                            app.kill("cached #" + numCached, true);
24519                        }
24520                        break;
24521                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
24522                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
24523                                && app.lastActivityTime < oldTime) {
24524                            app.kill("empty for "
24525                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
24526                                    / 1000) + "s", true);
24527                        } else {
24528                            numEmpty++;
24529                            if (numEmpty > emptyProcessLimit) {
24530                                app.kill("empty #" + numEmpty, true);
24531                            }
24532                        }
24533                        break;
24534                    default:
24535                        mNumNonCachedProcs++;
24536                        break;
24537                }
24538
24539                if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
24540                    // If this is an isolated process, there are no services
24541                    // running in it, and it's not a special process with a
24542                    // custom entry point, then the process is no longer
24543                    // needed.  We agressively kill these because we can by
24544                    // definition not re-use the same process again, and it is
24545                    // good to avoid having whatever code was running in them
24546                    // left sitting around after no longer needed.
24547                    app.kill("isolated not needed", true);
24548                } else {
24549                    // Keeping this process, update its uid.
24550                    final UidRecord uidRec = app.uidRecord;
24551                    if (uidRec != null) {
24552                        uidRec.ephemeral = app.info.isInstantApp();
24553                        if (uidRec.curProcState > app.curProcState) {
24554                            uidRec.curProcState = app.curProcState;
24555                        }
24556                        if (app.foregroundServices) {
24557                            uidRec.foregroundServices = true;
24558                        }
24559                    }
24560                }
24561
24562                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
24563                        && !app.killedByAm) {
24564                    numTrimming++;
24565                }
24566            }
24567        }
24568
24569        incrementProcStateSeqAndNotifyAppsLocked();
24570
24571        mNumServiceProcs = mNewNumServiceProcs;
24572
24573        // Now determine the memory trimming level of background processes.
24574        // Unfortunately we need to start at the back of the list to do this
24575        // properly.  We only do this if the number of background apps we
24576        // are managing to keep around is less than half the maximum we desire;
24577        // if we are keeping a good number around, we'll let them use whatever
24578        // memory they want.
24579        final int numCachedAndEmpty = numCached + numEmpty;
24580        int memFactor;
24581        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
24582                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
24583            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
24584                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
24585            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
24586                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
24587            } else {
24588                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
24589            }
24590        } else {
24591            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
24592        }
24593        // We always allow the memory level to go up (better).  We only allow it to go
24594        // down if we are in a state where that is allowed, *and* the total number of processes
24595        // has gone down since last time.
24596        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
24597                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
24598                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
24599        if (memFactor > mLastMemoryLevel) {
24600            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
24601                memFactor = mLastMemoryLevel;
24602                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
24603            }
24604        }
24605        if (memFactor != mLastMemoryLevel) {
24606            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
24607        }
24608        mLastMemoryLevel = memFactor;
24609        mLastNumProcesses = mLruProcesses.size();
24610        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
24611        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
24612        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
24613            if (mLowRamStartTime == 0) {
24614                mLowRamStartTime = now;
24615            }
24616            int step = 0;
24617            int fgTrimLevel;
24618            switch (memFactor) {
24619                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
24620                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
24621                    break;
24622                case ProcessStats.ADJ_MEM_FACTOR_LOW:
24623                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
24624                    break;
24625                default:
24626                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
24627                    break;
24628            }
24629            int factor = numTrimming/3;
24630            int minFactor = 2;
24631            if (mHomeProcess != null) minFactor++;
24632            if (mPreviousProcess != null) minFactor++;
24633            if (factor < minFactor) factor = minFactor;
24634            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
24635            for (int i=N-1; i>=0; i--) {
24636                ProcessRecord app = mLruProcesses.get(i);
24637                if (allChanged || app.procStateChanged) {
24638                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
24639                    app.procStateChanged = false;
24640                }
24641                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
24642                        && !app.killedByAm) {
24643                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
24644                        try {
24645                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24646                                    "Trimming memory of " + app.processName + " to " + curLevel);
24647                            app.thread.scheduleTrimMemory(curLevel);
24648                        } catch (RemoteException e) {
24649                        }
24650                        if (false) {
24651                            // For now we won't do this; our memory trimming seems
24652                            // to be good enough at this point that destroying
24653                            // activities causes more harm than good.
24654                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
24655                                    && app != mHomeProcess && app != mPreviousProcess) {
24656                                // Need to do this on its own message because the stack may not
24657                                // be in a consistent state at this point.
24658                                // For these apps we will also finish their activities
24659                                // to help them free memory.
24660                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
24661                            }
24662                        }
24663                    }
24664                    app.trimMemoryLevel = curLevel;
24665                    step++;
24666                    if (step >= factor) {
24667                        step = 0;
24668                        switch (curLevel) {
24669                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
24670                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
24671                                break;
24672                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
24673                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
24674                                break;
24675                        }
24676                    }
24677                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
24678                        && !app.killedByAm) {
24679                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
24680                            && app.thread != null) {
24681                        try {
24682                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24683                                    "Trimming memory of heavy-weight " + app.processName
24684                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
24685                            app.thread.scheduleTrimMemory(
24686                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
24687                        } catch (RemoteException e) {
24688                        }
24689                    }
24690                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
24691                } else {
24692                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
24693                            || app.systemNoUi) && app.pendingUiClean) {
24694                        // If this application is now in the background and it
24695                        // had done UI, then give it the special trim level to
24696                        // have it free UI resources.
24697                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
24698                        if (app.trimMemoryLevel < level && app.thread != null) {
24699                            try {
24700                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24701                                        "Trimming memory of bg-ui " + app.processName
24702                                        + " to " + level);
24703                                app.thread.scheduleTrimMemory(level);
24704                            } catch (RemoteException e) {
24705                            }
24706                        }
24707                        app.pendingUiClean = false;
24708                    }
24709                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
24710                        try {
24711                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24712                                    "Trimming memory of fg " + app.processName
24713                                    + " to " + fgTrimLevel);
24714                            app.thread.scheduleTrimMemory(fgTrimLevel);
24715                        } catch (RemoteException e) {
24716                        }
24717                    }
24718                    app.trimMemoryLevel = fgTrimLevel;
24719                }
24720            }
24721        } else {
24722            if (mLowRamStartTime != 0) {
24723                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
24724                mLowRamStartTime = 0;
24725            }
24726            for (int i=N-1; i>=0; i--) {
24727                ProcessRecord app = mLruProcesses.get(i);
24728                if (allChanged || app.procStateChanged) {
24729                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
24730                    app.procStateChanged = false;
24731                }
24732                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
24733                        || app.systemNoUi) && app.pendingUiClean) {
24734                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
24735                            && app.thread != null) {
24736                        try {
24737                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
24738                                    "Trimming memory of ui hidden " + app.processName
24739                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
24740                            app.thread.scheduleTrimMemory(
24741                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
24742                        } catch (RemoteException e) {
24743                        }
24744                    }
24745                    app.pendingUiClean = false;
24746                }
24747                app.trimMemoryLevel = 0;
24748            }
24749        }
24750
24751        if (mAlwaysFinishActivities) {
24752            // Need to do this on its own message because the stack may not
24753            // be in a consistent state at this point.
24754            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
24755        }
24756
24757        if (allChanged) {
24758            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
24759        }
24760
24761        ArrayList<UidRecord> becameIdle = null;
24762
24763        // Update from any uid changes.
24764        if (mLocalPowerManager != null) {
24765            mLocalPowerManager.startUidChanges();
24766        }
24767        for (int i=mActiveUids.size()-1; i>=0; i--) {
24768            final UidRecord uidRec = mActiveUids.valueAt(i);
24769            int uidChange = UidRecord.CHANGE_PROCSTATE;
24770            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
24771                    && (uidRec.setProcState != uidRec.curProcState
24772                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
24773                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
24774                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
24775                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
24776                        + " to " + uidRec.curWhitelist);
24777                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
24778                        && !uidRec.curWhitelist) {
24779                    // UID is now in the background (and not on the temp whitelist).  Was it
24780                    // previously in the foreground (or on the temp whitelist)?
24781                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
24782                            || uidRec.setWhitelist) {
24783                        uidRec.lastBackgroundTime = nowElapsed;
24784                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
24785                            // Note: the background settle time is in elapsed realtime, while
24786                            // the handler time base is uptime.  All this means is that we may
24787                            // stop background uids later than we had intended, but that only
24788                            // happens because the device was sleeping so we are okay anyway.
24789                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
24790                                    mConstants.BACKGROUND_SETTLE_TIME);
24791                        }
24792                    }
24793                    if (uidRec.idle && !uidRec.setIdle) {
24794                        uidChange = UidRecord.CHANGE_IDLE;
24795                        if (becameIdle == null) {
24796                            becameIdle = new ArrayList<>();
24797                        }
24798                        becameIdle.add(uidRec);
24799                    }
24800                } else {
24801                    if (uidRec.idle) {
24802                        uidChange = UidRecord.CHANGE_ACTIVE;
24803                        EventLogTags.writeAmUidActive(uidRec.uid);
24804                        uidRec.idle = false;
24805                    }
24806                    uidRec.lastBackgroundTime = 0;
24807                }
24808                final boolean wasCached = uidRec.setProcState
24809                        > ActivityManager.PROCESS_STATE_RECEIVER;
24810                final boolean isCached = uidRec.curProcState
24811                        > ActivityManager.PROCESS_STATE_RECEIVER;
24812                if (wasCached != isCached ||
24813                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
24814                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
24815                }
24816                uidRec.setProcState = uidRec.curProcState;
24817                uidRec.setWhitelist = uidRec.curWhitelist;
24818                uidRec.setIdle = uidRec.idle;
24819                enqueueUidChangeLocked(uidRec, -1, uidChange);
24820                noteUidProcessState(uidRec.uid, uidRec.curProcState);
24821                if (uidRec.foregroundServices) {
24822                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
24823                }
24824            }
24825        }
24826        if (mLocalPowerManager != null) {
24827            mLocalPowerManager.finishUidChanges();
24828        }
24829
24830        if (becameIdle != null) {
24831            // If we have any new uids that became idle this time, we need to make sure
24832            // they aren't left with running services.
24833            for (int i = becameIdle.size() - 1; i >= 0; i--) {
24834                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
24835            }
24836        }
24837
24838        if (mProcessStats.shouldWriteNowLocked(now)) {
24839            mHandler.post(new Runnable() {
24840                @Override public void run() {
24841                    synchronized (ActivityManagerService.this) {
24842                        mProcessStats.writeStateAsyncLocked();
24843                    }
24844                }
24845            });
24846        }
24847
24848        if (DEBUG_OOM_ADJ) {
24849            final long duration = SystemClock.uptimeMillis() - now;
24850            if (false) {
24851                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
24852                        new RuntimeException("here").fillInStackTrace());
24853            } else {
24854                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
24855            }
24856        }
24857    }
24858
24859    @Override
24860    public void makePackageIdle(String packageName, int userId) {
24861        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
24862                != PackageManager.PERMISSION_GRANTED) {
24863            String msg = "Permission Denial: makePackageIdle() from pid="
24864                    + Binder.getCallingPid()
24865                    + ", uid=" + Binder.getCallingUid()
24866                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
24867            Slog.w(TAG, msg);
24868            throw new SecurityException(msg);
24869        }
24870        final int callingPid = Binder.getCallingPid();
24871        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
24872                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
24873        long callingId = Binder.clearCallingIdentity();
24874        synchronized(this) {
24875            try {
24876                IPackageManager pm = AppGlobals.getPackageManager();
24877                int pkgUid = -1;
24878                try {
24879                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
24880                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
24881                } catch (RemoteException e) {
24882                }
24883                if (pkgUid == -1) {
24884                    throw new IllegalArgumentException("Unknown package name " + packageName);
24885                }
24886
24887                if (mLocalPowerManager != null) {
24888                    mLocalPowerManager.startUidChanges();
24889                }
24890                final int appId = UserHandle.getAppId(pkgUid);
24891                final int N = mActiveUids.size();
24892                for (int i=N-1; i>=0; i--) {
24893                    final UidRecord uidRec = mActiveUids.valueAt(i);
24894                    final long bgTime = uidRec.lastBackgroundTime;
24895                    if (bgTime > 0 && !uidRec.idle) {
24896                        if (UserHandle.getAppId(uidRec.uid) == appId) {
24897                            if (userId == UserHandle.USER_ALL ||
24898                                    userId == UserHandle.getUserId(uidRec.uid)) {
24899                                EventLogTags.writeAmUidIdle(uidRec.uid);
24900                                uidRec.idle = true;
24901                                uidRec.setIdle = true;
24902                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
24903                                        + " from package " + packageName + " user " + userId);
24904                                doStopUidLocked(uidRec.uid, uidRec);
24905                            }
24906                        }
24907                    }
24908                }
24909            } finally {
24910                if (mLocalPowerManager != null) {
24911                    mLocalPowerManager.finishUidChanges();
24912                }
24913                Binder.restoreCallingIdentity(callingId);
24914            }
24915        }
24916    }
24917
24918    final void idleUids() {
24919        synchronized (this) {
24920            final int N = mActiveUids.size();
24921            if (N <= 0) {
24922                return;
24923            }
24924            final long nowElapsed = SystemClock.elapsedRealtime();
24925            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
24926            long nextTime = 0;
24927            if (mLocalPowerManager != null) {
24928                mLocalPowerManager.startUidChanges();
24929            }
24930            for (int i=N-1; i>=0; i--) {
24931                final UidRecord uidRec = mActiveUids.valueAt(i);
24932                final long bgTime = uidRec.lastBackgroundTime;
24933                if (bgTime > 0 && !uidRec.idle) {
24934                    if (bgTime <= maxBgTime) {
24935                        EventLogTags.writeAmUidIdle(uidRec.uid);
24936                        uidRec.idle = true;
24937                        uidRec.setIdle = true;
24938                        doStopUidLocked(uidRec.uid, uidRec);
24939                    } else {
24940                        if (nextTime == 0 || nextTime > bgTime) {
24941                            nextTime = bgTime;
24942                        }
24943                    }
24944                }
24945            }
24946            if (mLocalPowerManager != null) {
24947                mLocalPowerManager.finishUidChanges();
24948            }
24949            if (nextTime > 0) {
24950                mHandler.removeMessages(IDLE_UIDS_MSG);
24951                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
24952                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
24953            }
24954        }
24955    }
24956
24957    /**
24958     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
24959     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
24960     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
24961     */
24962    @VisibleForTesting
24963    @GuardedBy("this")
24964    void incrementProcStateSeqAndNotifyAppsLocked() {
24965        if (mWaitForNetworkTimeoutMs <= 0) {
24966            return;
24967        }
24968        // Used for identifying which uids need to block for network.
24969        ArrayList<Integer> blockingUids = null;
24970        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
24971            final UidRecord uidRec = mActiveUids.valueAt(i);
24972            // If the network is not restricted for uid, then nothing to do here.
24973            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
24974                continue;
24975            }
24976            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
24977                continue;
24978            }
24979            // If process state is not changed, then there's nothing to do.
24980            if (uidRec.setProcState == uidRec.curProcState) {
24981                continue;
24982            }
24983            final int blockState = getBlockStateForUid(uidRec);
24984            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
24985            // there's nothing the app needs to do in this scenario.
24986            if (blockState == NETWORK_STATE_NO_CHANGE) {
24987                continue;
24988            }
24989            synchronized (uidRec.networkStateLock) {
24990                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
24991                if (blockState == NETWORK_STATE_BLOCK) {
24992                    if (blockingUids == null) {
24993                        blockingUids = new ArrayList<>();
24994                    }
24995                    blockingUids.add(uidRec.uid);
24996                } else {
24997                    if (DEBUG_NETWORK) {
24998                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
24999                                + " threads for uid: " + uidRec);
25000                    }
25001                    if (uidRec.waitingForNetwork) {
25002                        uidRec.networkStateLock.notifyAll();
25003                    }
25004                }
25005            }
25006        }
25007
25008        // There are no uids that need to block, so nothing more to do.
25009        if (blockingUids == null) {
25010            return;
25011        }
25012
25013        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
25014            final ProcessRecord app = mLruProcesses.get(i);
25015            if (!blockingUids.contains(app.uid)) {
25016                continue;
25017            }
25018            if (!app.killedByAm && app.thread != null) {
25019                final UidRecord uidRec = mActiveUids.get(app.uid);
25020                try {
25021                    if (DEBUG_NETWORK) {
25022                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
25023                                + uidRec);
25024                    }
25025                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
25026                } catch (RemoteException ignored) {
25027                }
25028            }
25029        }
25030    }
25031
25032    /**
25033     * Checks if the uid is coming from background to foreground or vice versa and returns
25034     * appropriate block state based on this.
25035     *
25036     * @return blockState based on whether the uid is coming from background to foreground or
25037     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
25038     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
25039     *         {@link #NETWORK_STATE_NO_CHANGE}.
25040     */
25041    @VisibleForTesting
25042    int getBlockStateForUid(UidRecord uidRec) {
25043        // Denotes whether uid's process state is currently allowed network access.
25044        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
25045                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
25046        // Denotes whether uid's process state was previously allowed network access.
25047        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
25048                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
25049
25050        // When the uid is coming to foreground, AMS should inform the app thread that it should
25051        // block for the network rules to get updated before launching an activity.
25052        if (!wasAllowed && isAllowed) {
25053            return NETWORK_STATE_BLOCK;
25054        }
25055        // When the uid is going to background, AMS should inform the app thread that if an
25056        // activity launch is blocked for the network rules to get updated, it should be unblocked.
25057        if (wasAllowed && !isAllowed) {
25058            return NETWORK_STATE_UNBLOCK;
25059        }
25060        return NETWORK_STATE_NO_CHANGE;
25061    }
25062
25063    final void runInBackgroundDisabled(int uid) {
25064        synchronized (this) {
25065            UidRecord uidRec = mActiveUids.get(uid);
25066            if (uidRec != null) {
25067                // This uid is actually running...  should it be considered background now?
25068                if (uidRec.idle) {
25069                    doStopUidLocked(uidRec.uid, uidRec);
25070                }
25071            } else {
25072                // This uid isn't actually running...  still send a report about it being "stopped".
25073                doStopUidLocked(uid, null);
25074            }
25075        }
25076    }
25077
25078    /**
25079     * Call {@link #doStopUidLocked} (which will also stop background services) for all idle UIDs.
25080     */
25081    void doStopUidForIdleUidsLocked() {
25082        final int size = mActiveUids.size();
25083        for (int i = 0; i < size; i++) {
25084            final int uid = mActiveUids.keyAt(i);
25085            if (UserHandle.isCore(uid)) {
25086                continue;
25087            }
25088            final UidRecord uidRec = mActiveUids.valueAt(i);
25089            if (!uidRec.idle) {
25090                continue;
25091            }
25092            doStopUidLocked(uidRec.uid, uidRec);
25093        }
25094    }
25095
25096    final void doStopUidLocked(int uid, final UidRecord uidRec) {
25097        mServices.stopInBackgroundLocked(uid);
25098        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
25099    }
25100
25101    /**
25102     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25103     */
25104    @GuardedBy("this")
25105    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
25106            long duration, String tag) {
25107        if (DEBUG_WHITELISTS) {
25108            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
25109                    + targetUid + ", " + duration + ")");
25110        }
25111
25112        synchronized (mPidsSelfLocked) {
25113            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
25114            if (pr == null) {
25115                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
25116                        + callerPid);
25117                return;
25118            }
25119            if (!pr.whitelistManager) {
25120                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
25121                        != PackageManager.PERMISSION_GRANTED) {
25122                    if (DEBUG_WHITELISTS) {
25123                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
25124                                + ": pid " + callerPid + " is not allowed");
25125                    }
25126                    return;
25127                }
25128            }
25129        }
25130
25131        tempWhitelistUidLocked(targetUid, duration, tag);
25132    }
25133
25134    /**
25135     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
25136     */
25137    @GuardedBy("this")
25138    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
25139        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
25140        setUidTempWhitelistStateLocked(targetUid, true);
25141        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
25142    }
25143
25144    void pushTempWhitelist() {
25145        final int N;
25146        final PendingTempWhitelist[] list;
25147
25148        // First copy out the pending changes...  we need to leave them in the map for now,
25149        // in case someone needs to check what is coming up while we don't have the lock held.
25150        synchronized(this) {
25151            N = mPendingTempWhitelist.size();
25152            list = new PendingTempWhitelist[N];
25153            for (int i = 0; i < N; i++) {
25154                list[i] = mPendingTempWhitelist.valueAt(i);
25155            }
25156        }
25157
25158        // Now safely dispatch changes to device idle controller.
25159        for (int i = 0; i < N; i++) {
25160            PendingTempWhitelist ptw = list[i];
25161            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
25162                    ptw.duration, true, ptw.tag);
25163        }
25164
25165        // And now we can safely remove them from the map.
25166        synchronized(this) {
25167            for (int i = 0; i < N; i++) {
25168                PendingTempWhitelist ptw = list[i];
25169                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
25170                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
25171                    mPendingTempWhitelist.removeAt(index);
25172                }
25173            }
25174        }
25175    }
25176
25177    @GuardedBy("this")
25178    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
25179        boolean changed = false;
25180        for (int i=mActiveUids.size()-1; i>=0; i--) {
25181            final UidRecord uidRec = mActiveUids.valueAt(i);
25182            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
25183                uidRec.curWhitelist = onWhitelist;
25184                changed = true;
25185            }
25186        }
25187        if (changed) {
25188            updateOomAdjLocked();
25189        }
25190    }
25191
25192    @GuardedBy("this")
25193    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
25194        boolean changed = false;
25195        final UidRecord uidRec = mActiveUids.get(uid);
25196        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
25197            uidRec.curWhitelist = onWhitelist;
25198            updateOomAdjLocked();
25199        }
25200    }
25201
25202    final void trimApplications() {
25203        synchronized (this) {
25204            int i;
25205
25206            // First remove any unused application processes whose package
25207            // has been removed.
25208            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
25209                final ProcessRecord app = mRemovedProcesses.get(i);
25210                if (app.activities.size() == 0 && app.recentTasks.size() == 0
25211                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
25212                    Slog.i(
25213                        TAG, "Exiting empty application process "
25214                        + app.toShortString() + " ("
25215                        + (app.thread != null ? app.thread.asBinder() : null)
25216                        + ")\n");
25217                    if (app.pid > 0 && app.pid != MY_PID) {
25218                        app.kill("empty", false);
25219                    } else if (app.thread != null) {
25220                        try {
25221                            app.thread.scheduleExit();
25222                        } catch (Exception e) {
25223                            // Ignore exceptions.
25224                        }
25225                    }
25226                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
25227                    mRemovedProcesses.remove(i);
25228
25229                    if (app.persistent) {
25230                        addAppLocked(app.info, null, false, null /* ABI override */);
25231                    }
25232                }
25233            }
25234
25235            // Now update the oom adj for all processes.
25236            updateOomAdjLocked();
25237        }
25238    }
25239
25240    /** This method sends the specified signal to each of the persistent apps */
25241    public void signalPersistentProcesses(int sig) throws RemoteException {
25242        if (sig != SIGNAL_USR1) {
25243            throw new SecurityException("Only SIGNAL_USR1 is allowed");
25244        }
25245
25246        synchronized (this) {
25247            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
25248                    != PackageManager.PERMISSION_GRANTED) {
25249                throw new SecurityException("Requires permission "
25250                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
25251            }
25252
25253            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
25254                ProcessRecord r = mLruProcesses.get(i);
25255                if (r.thread != null && r.persistent) {
25256                    sendSignal(r.pid, sig);
25257                }
25258            }
25259        }
25260    }
25261
25262    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
25263        if (proc == null || proc == mProfileProc) {
25264            proc = mProfileProc;
25265            profileType = mProfileType;
25266            clearProfilerLocked();
25267        }
25268        if (proc == null) {
25269            return;
25270        }
25271        try {
25272            proc.thread.profilerControl(false, null, profileType);
25273        } catch (RemoteException e) {
25274            throw new IllegalStateException("Process disappeared");
25275        }
25276    }
25277
25278    private void clearProfilerLocked() {
25279        if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
25280            try {
25281                mProfilerInfo.profileFd.close();
25282            } catch (IOException e) {
25283            }
25284        }
25285        mProfileApp = null;
25286        mProfileProc = null;
25287        mProfilerInfo = null;
25288    }
25289
25290    public boolean profileControl(String process, int userId, boolean start,
25291            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
25292
25293        try {
25294            synchronized (this) {
25295                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
25296                // its own permission.
25297                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25298                        != PackageManager.PERMISSION_GRANTED) {
25299                    throw new SecurityException("Requires permission "
25300                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25301                }
25302
25303                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
25304                    throw new IllegalArgumentException("null profile info or fd");
25305                }
25306
25307                ProcessRecord proc = null;
25308                if (process != null) {
25309                    proc = findProcessLocked(process, userId, "profileControl");
25310                }
25311
25312                if (start && (proc == null || proc.thread == null)) {
25313                    throw new IllegalArgumentException("Unknown process: " + process);
25314                }
25315
25316                if (start) {
25317                    stopProfilerLocked(null, 0);
25318                    setProfileApp(proc.info, proc.processName, profilerInfo);
25319                    mProfileProc = proc;
25320                    mProfileType = profileType;
25321                    ParcelFileDescriptor fd = profilerInfo.profileFd;
25322                    try {
25323                        fd = fd.dup();
25324                    } catch (IOException e) {
25325                        fd = null;
25326                    }
25327                    profilerInfo.profileFd = fd;
25328                    proc.thread.profilerControl(start, profilerInfo, profileType);
25329                    fd = null;
25330                    try {
25331                        mProfilerInfo.profileFd.close();
25332                    } catch (IOException e) {
25333                    }
25334                    mProfilerInfo.profileFd = null;
25335                } else {
25336                    stopProfilerLocked(proc, profileType);
25337                    if (profilerInfo != null && profilerInfo.profileFd != null) {
25338                        try {
25339                            profilerInfo.profileFd.close();
25340                        } catch (IOException e) {
25341                        }
25342                    }
25343                }
25344
25345                return true;
25346            }
25347        } catch (RemoteException e) {
25348            throw new IllegalStateException("Process disappeared");
25349        } finally {
25350            if (profilerInfo != null && profilerInfo.profileFd != null) {
25351                try {
25352                    profilerInfo.profileFd.close();
25353                } catch (IOException e) {
25354                }
25355            }
25356        }
25357    }
25358
25359    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
25360        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
25361                userId, true, ALLOW_FULL_ONLY, callName, null);
25362        ProcessRecord proc = null;
25363        try {
25364            int pid = Integer.parseInt(process);
25365            synchronized (mPidsSelfLocked) {
25366                proc = mPidsSelfLocked.get(pid);
25367            }
25368        } catch (NumberFormatException e) {
25369        }
25370
25371        if (proc == null) {
25372            ArrayMap<String, SparseArray<ProcessRecord>> all
25373                    = mProcessNames.getMap();
25374            SparseArray<ProcessRecord> procs = all.get(process);
25375            if (procs != null && procs.size() > 0) {
25376                proc = procs.valueAt(0);
25377                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
25378                    for (int i=1; i<procs.size(); i++) {
25379                        ProcessRecord thisProc = procs.valueAt(i);
25380                        if (thisProc.userId == userId) {
25381                            proc = thisProc;
25382                            break;
25383                        }
25384                    }
25385                }
25386            }
25387        }
25388
25389        return proc;
25390    }
25391
25392    public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
25393            boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
25394
25395        try {
25396            synchronized (this) {
25397                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
25398                // its own permission (same as profileControl).
25399                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25400                        != PackageManager.PERMISSION_GRANTED) {
25401                    throw new SecurityException("Requires permission "
25402                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25403                }
25404
25405                if (fd == null) {
25406                    throw new IllegalArgumentException("null fd");
25407                }
25408
25409                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
25410                if (proc == null || proc.thread == null) {
25411                    throw new IllegalArgumentException("Unknown process: " + process);
25412                }
25413
25414                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25415                if (!isDebuggable) {
25416                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25417                        throw new SecurityException("Process not debuggable: " + proc);
25418                    }
25419                }
25420
25421                proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
25422                fd = null;
25423                return true;
25424            }
25425        } catch (RemoteException e) {
25426            throw new IllegalStateException("Process disappeared");
25427        } finally {
25428            if (fd != null) {
25429                try {
25430                    fd.close();
25431                } catch (IOException e) {
25432                }
25433            }
25434        }
25435    }
25436
25437    @Override
25438    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
25439            String reportPackage) {
25440        if (processName != null) {
25441            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
25442                    "setDumpHeapDebugLimit()");
25443        } else {
25444            synchronized (mPidsSelfLocked) {
25445                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
25446                if (proc == null) {
25447                    throw new SecurityException("No process found for calling pid "
25448                            + Binder.getCallingPid());
25449                }
25450                if (!Build.IS_DEBUGGABLE
25451                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25452                    throw new SecurityException("Not running a debuggable build");
25453                }
25454                processName = proc.processName;
25455                uid = proc.uid;
25456                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
25457                    throw new SecurityException("Package " + reportPackage + " is not running in "
25458                            + proc);
25459                }
25460            }
25461        }
25462        synchronized (this) {
25463            if (maxMemSize > 0) {
25464                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
25465            } else {
25466                if (uid != 0) {
25467                    mMemWatchProcesses.remove(processName, uid);
25468                } else {
25469                    mMemWatchProcesses.getMap().remove(processName);
25470                }
25471            }
25472        }
25473    }
25474
25475    @Override
25476    public void dumpHeapFinished(String path) {
25477        synchronized (this) {
25478            if (Binder.getCallingPid() != mMemWatchDumpPid) {
25479                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
25480                        + " does not match last pid " + mMemWatchDumpPid);
25481                return;
25482            }
25483            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
25484                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
25485                        + " does not match last path " + mMemWatchDumpFile);
25486                return;
25487            }
25488            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
25489            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
25490
25491            // Forced gc to clean up the remnant hprof fd.
25492            Runtime.getRuntime().gc();
25493        }
25494    }
25495
25496    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
25497    public void monitor() {
25498        synchronized (this) { }
25499    }
25500
25501    void onCoreSettingsChange(Bundle settings) {
25502        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
25503            ProcessRecord processRecord = mLruProcesses.get(i);
25504            try {
25505                if (processRecord.thread != null) {
25506                    processRecord.thread.setCoreSettings(settings);
25507                }
25508            } catch (RemoteException re) {
25509                /* ignore */
25510            }
25511        }
25512    }
25513
25514    // Multi-user methods
25515
25516    /**
25517     * Start user, if its not already running, but don't bring it to foreground.
25518     */
25519    @Override
25520    public boolean startUserInBackground(final int userId) {
25521        return startUserInBackgroundWithListener(userId, null);
25522    }
25523
25524    @Override
25525    public boolean startUserInBackgroundWithListener(final int userId,
25526                @Nullable IProgressListener unlockListener) {
25527        return mUserController.startUser(userId, /* foreground */ false, unlockListener);
25528    }
25529
25530    @Override
25531    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
25532        return mUserController.unlockUser(userId, token, secret, listener);
25533    }
25534
25535    @Override
25536    public boolean switchUser(final int targetUserId) {
25537        return mUserController.switchUser(targetUserId);
25538    }
25539
25540    @Override
25541    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
25542        return mUserController.stopUser(userId, force, callback);
25543    }
25544
25545    @Override
25546    public UserInfo getCurrentUser() {
25547        return mUserController.getCurrentUser();
25548    }
25549
25550    String getStartedUserState(int userId) {
25551        final UserState userState = mUserController.getStartedUserState(userId);
25552        return UserState.stateToString(userState.state);
25553    }
25554
25555    @Override
25556    public boolean isUserRunning(int userId, int flags) {
25557        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
25558                && checkCallingPermission(INTERACT_ACROSS_USERS)
25559                    != PackageManager.PERMISSION_GRANTED) {
25560            String msg = "Permission Denial: isUserRunning() from pid="
25561                    + Binder.getCallingPid()
25562                    + ", uid=" + Binder.getCallingUid()
25563                    + " requires " + INTERACT_ACROSS_USERS;
25564            Slog.w(TAG, msg);
25565            throw new SecurityException(msg);
25566        }
25567        return mUserController.isUserRunning(userId, flags);
25568    }
25569
25570    @Override
25571    public int[] getRunningUserIds() {
25572        if (checkCallingPermission(INTERACT_ACROSS_USERS)
25573                != PackageManager.PERMISSION_GRANTED) {
25574            String msg = "Permission Denial: isUserRunning() from pid="
25575                    + Binder.getCallingPid()
25576                    + ", uid=" + Binder.getCallingUid()
25577                    + " requires " + INTERACT_ACROSS_USERS;
25578            Slog.w(TAG, msg);
25579            throw new SecurityException(msg);
25580        }
25581        return mUserController.getStartedUserArray();
25582    }
25583
25584    @Override
25585    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
25586        mUserController.registerUserSwitchObserver(observer, name);
25587    }
25588
25589    @Override
25590    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
25591        mUserController.unregisterUserSwitchObserver(observer);
25592    }
25593
25594    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
25595        if (info == null) return null;
25596        ApplicationInfo newInfo = new ApplicationInfo(info);
25597        newInfo.initForUser(userId);
25598        return newInfo;
25599    }
25600
25601    public boolean isUserStopped(int userId) {
25602        return mUserController.getStartedUserState(userId) == null;
25603    }
25604
25605    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
25606        if (aInfo == null
25607                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
25608            return aInfo;
25609        }
25610
25611        ActivityInfo info = new ActivityInfo(aInfo);
25612        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
25613        return info;
25614    }
25615
25616    private boolean processSanityChecksLocked(ProcessRecord process) {
25617        if (process == null || process.thread == null) {
25618            return false;
25619        }
25620
25621        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
25622        if (!isDebuggable) {
25623            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
25624                return false;
25625            }
25626        }
25627
25628        return true;
25629    }
25630
25631    public boolean startBinderTracking() throws RemoteException {
25632        synchronized (this) {
25633            mBinderTransactionTrackingEnabled = true;
25634            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
25635            // permission (same as profileControl).
25636            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25637                    != PackageManager.PERMISSION_GRANTED) {
25638                throw new SecurityException("Requires permission "
25639                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25640            }
25641
25642            for (int i = 0; i < mLruProcesses.size(); i++) {
25643                ProcessRecord process = mLruProcesses.get(i);
25644                if (!processSanityChecksLocked(process)) {
25645                    continue;
25646                }
25647                try {
25648                    process.thread.startBinderTracking();
25649                } catch (RemoteException e) {
25650                    Log.v(TAG, "Process disappared");
25651                }
25652            }
25653            return true;
25654        }
25655    }
25656
25657    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
25658        try {
25659            synchronized (this) {
25660                mBinderTransactionTrackingEnabled = false;
25661                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
25662                // permission (same as profileControl).
25663                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
25664                        != PackageManager.PERMISSION_GRANTED) {
25665                    throw new SecurityException("Requires permission "
25666                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
25667                }
25668
25669                if (fd == null) {
25670                    throw new IllegalArgumentException("null fd");
25671                }
25672
25673                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
25674                pw.println("Binder transaction traces for all processes.\n");
25675                for (ProcessRecord process : mLruProcesses) {
25676                    if (!processSanityChecksLocked(process)) {
25677                        continue;
25678                    }
25679
25680                    pw.println("Traces for process: " + process.processName);
25681                    pw.flush();
25682                    try {
25683                        TransferPipe tp = new TransferPipe();
25684                        try {
25685                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
25686                            tp.go(fd.getFileDescriptor());
25687                        } finally {
25688                            tp.kill();
25689                        }
25690                    } catch (IOException e) {
25691                        pw.println("Failure while dumping IPC traces from " + process +
25692                                ".  Exception: " + e);
25693                        pw.flush();
25694                    } catch (RemoteException e) {
25695                        pw.println("Got a RemoteException while dumping IPC traces from " +
25696                                process + ".  Exception: " + e);
25697                        pw.flush();
25698                    }
25699                }
25700                fd = null;
25701                return true;
25702            }
25703        } finally {
25704            if (fd != null) {
25705                try {
25706                    fd.close();
25707                } catch (IOException e) {
25708                }
25709            }
25710        }
25711    }
25712
25713    @VisibleForTesting
25714    final class LocalService extends ActivityManagerInternal {
25715        @Override
25716        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
25717                int targetUserId) {
25718            synchronized (ActivityManagerService.this) {
25719                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
25720                        targetPkg, intent, null, targetUserId);
25721            }
25722        }
25723
25724        @Override
25725        public String checkContentProviderAccess(String authority, int userId) {
25726            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
25727        }
25728
25729        @Override
25730        public void onWakefulnessChanged(int wakefulness) {
25731            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
25732        }
25733
25734        @Override
25735        public boolean startIsolatedProcess(String entryPoint, String[] entryPointArgs,
25736                String processName, String abiOverride, int uid, Runnable crashHandler) {
25737            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
25738                    processName, abiOverride, uid, crashHandler);
25739        }
25740
25741        @Override
25742        public SleepToken acquireSleepToken(String tag, int displayId) {
25743            Preconditions.checkNotNull(tag);
25744            return ActivityManagerService.this.acquireSleepToken(tag, displayId);
25745        }
25746
25747        @Override
25748        public ComponentName getHomeActivityForUser(int userId) {
25749            synchronized (ActivityManagerService.this) {
25750                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
25751                return homeActivity == null ? null : homeActivity.realActivity;
25752            }
25753        }
25754
25755        @Override
25756        public void onUserRemoved(int userId) {
25757            synchronized (ActivityManagerService.this) {
25758                ActivityManagerService.this.onUserStoppedLocked(userId);
25759            }
25760            mBatteryStatsService.onUserRemoved(userId);
25761            mUserController.onUserRemoved(userId);
25762        }
25763
25764        @Override
25765        public void onLocalVoiceInteractionStarted(IBinder activity,
25766                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
25767            synchronized (ActivityManagerService.this) {
25768                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
25769                        voiceSession, voiceInteractor);
25770            }
25771        }
25772
25773        @Override
25774        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
25775            synchronized (ActivityManagerService.this) {
25776                mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
25777                        reasons, timestamp);
25778            }
25779        }
25780
25781        @Override
25782        public void notifyAppTransitionFinished() {
25783            synchronized (ActivityManagerService.this) {
25784                mStackSupervisor.notifyAppTransitionDone();
25785                mKeyguardController.notifyAppTransitionDone();
25786            }
25787        }
25788
25789        @Override
25790        public void notifyAppTransitionCancelled() {
25791            synchronized (ActivityManagerService.this) {
25792                mStackSupervisor.notifyAppTransitionDone();
25793            }
25794        }
25795
25796        @Override
25797        public List<IBinder> getTopVisibleActivities() {
25798            synchronized (ActivityManagerService.this) {
25799                return mStackSupervisor.getTopVisibleActivities();
25800            }
25801        }
25802
25803        @Override
25804        public void notifyDockedStackMinimizedChanged(boolean minimized) {
25805            synchronized (ActivityManagerService.this) {
25806                mStackSupervisor.setDockedStackMinimized(minimized);
25807            }
25808        }
25809
25810        @Override
25811        public void killForegroundAppsForUser(int userHandle) {
25812            synchronized (ActivityManagerService.this) {
25813                final ArrayList<ProcessRecord> procs = new ArrayList<>();
25814                final int NP = mProcessNames.getMap().size();
25815                for (int ip = 0; ip < NP; ip++) {
25816                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
25817                    final int NA = apps.size();
25818                    for (int ia = 0; ia < NA; ia++) {
25819                        final ProcessRecord app = apps.valueAt(ia);
25820                        if (app.persistent) {
25821                            // We don't kill persistent processes.
25822                            continue;
25823                        }
25824                        if (app.removed) {
25825                            procs.add(app);
25826                        } else if (app.userId == userHandle && app.foregroundActivities) {
25827                            app.removed = true;
25828                            procs.add(app);
25829                        }
25830                    }
25831                }
25832
25833                final int N = procs.size();
25834                for (int i = 0; i < N; i++) {
25835                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
25836                }
25837            }
25838        }
25839
25840        @Override
25841        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
25842                long duration) {
25843            if (!(target instanceof PendingIntentRecord)) {
25844                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
25845                return;
25846            }
25847            synchronized (ActivityManagerService.this) {
25848                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
25849            }
25850        }
25851
25852        @Override
25853        public void setDeviceIdleWhitelist(int[] appids) {
25854            synchronized (ActivityManagerService.this) {
25855                mDeviceIdleWhitelist = appids;
25856            }
25857        }
25858
25859        @Override
25860        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
25861            synchronized (ActivityManagerService.this) {
25862                mDeviceIdleTempWhitelist = appids;
25863                setAppIdTempWhitelistStateLocked(changingAppId, adding);
25864            }
25865        }
25866
25867        @Override
25868        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
25869                int userId) {
25870            Preconditions.checkNotNull(values, "Configuration must not be null");
25871            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
25872            synchronized (ActivityManagerService.this) {
25873                updateConfigurationLocked(values, null, false, true, userId,
25874                        false /* deferResume */);
25875            }
25876        }
25877
25878        @Override
25879        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
25880                Bundle bOptions) {
25881            Preconditions.checkNotNull(intents, "intents");
25882            final String[] resolvedTypes = new String[intents.length];
25883            for (int i = 0; i < intents.length; i++) {
25884                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
25885            }
25886
25887            // UID of the package on user userId.
25888            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
25889            // packageUid may not be initialized.
25890            int packageUid = 0;
25891            final long ident = Binder.clearCallingIdentity();
25892            try {
25893                packageUid = AppGlobals.getPackageManager().getPackageUid(
25894                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
25895            } catch (RemoteException e) {
25896                // Shouldn't happen.
25897            } finally {
25898                Binder.restoreCallingIdentity(ident);
25899            }
25900
25901            synchronized (ActivityManagerService.this) {
25902                return mActivityStartController.startActivitiesInPackage(
25903                        packageUid, packageName,
25904                        intents, resolvedTypes, null /* resultTo */,
25905                        SafeActivityOptions.fromBundle(bOptions), userId,
25906                        false /* validateIncomingUser */);
25907            }
25908        }
25909
25910        @Override
25911        public int getUidProcessState(int uid) {
25912            return getUidState(uid);
25913        }
25914
25915        @Override
25916        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
25917            synchronized (ActivityManagerService.this) {
25918
25919                // We might change the visibilities here, so prepare an empty app transition which
25920                // might be overridden later if we actually change visibilities.
25921                final boolean wasTransitionSet =
25922                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
25923                if (!wasTransitionSet) {
25924                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
25925                            false /* alwaysKeepCurrent */);
25926                }
25927                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
25928
25929                // If there was a transition set already we don't want to interfere with it as we
25930                // might be starting it too early.
25931                if (!wasTransitionSet) {
25932                    mWindowManager.executeAppTransition();
25933                }
25934            }
25935            if (callback != null) {
25936                callback.run();
25937            }
25938        }
25939
25940        @Override
25941        public boolean isSystemReady() {
25942            // no need to synchronize(this) just to read & return the value
25943            return mSystemReady;
25944        }
25945
25946        @Override
25947        public void notifyKeyguardTrustedChanged() {
25948            synchronized (ActivityManagerService.this) {
25949                if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
25950                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
25951                }
25952            }
25953        }
25954
25955        /**
25956         * Sets if the given pid has an overlay UI or not.
25957         *
25958         * @param pid The pid we are setting overlay UI for.
25959         * @param hasOverlayUi True if the process has overlay UI.
25960         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
25961         */
25962        @Override
25963        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
25964            synchronized (ActivityManagerService.this) {
25965                final ProcessRecord pr;
25966                synchronized (mPidsSelfLocked) {
25967                    pr = mPidsSelfLocked.get(pid);
25968                    if (pr == null) {
25969                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
25970                        return;
25971                    }
25972                }
25973                if (pr.hasOverlayUi == hasOverlayUi) {
25974                    return;
25975                }
25976                pr.hasOverlayUi = hasOverlayUi;
25977                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
25978                updateOomAdjLocked(pr, true);
25979            }
25980        }
25981
25982        @Override
25983        public void setRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
25984            ActivityManagerService.this.setRunningRemoteAnimation(pid, runningRemoteAnimation);
25985        }
25986
25987        /**
25988         * Called after the network policy rules are updated by
25989         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
25990         * and {@param procStateSeq}.
25991         */
25992        @Override
25993        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
25994            if (DEBUG_NETWORK) {
25995                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
25996                        + uid + " seq: " + procStateSeq);
25997            }
25998            UidRecord record;
25999            synchronized (ActivityManagerService.this) {
26000                record = mActiveUids.get(uid);
26001                if (record == null) {
26002                    if (DEBUG_NETWORK) {
26003                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
26004                                + " procStateSeq: " + procStateSeq);
26005                    }
26006                    return;
26007                }
26008            }
26009            synchronized (record.networkStateLock) {
26010                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
26011                    if (DEBUG_NETWORK) {
26012                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
26013                                + " been handled for uid: " + uid);
26014                    }
26015                    return;
26016                }
26017                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
26018                if (record.curProcStateSeq > procStateSeq) {
26019                    if (DEBUG_NETWORK) {
26020                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
26021                                + ", curProcstateSeq: " + record.curProcStateSeq
26022                                + ", procStateSeq: " + procStateSeq);
26023                    }
26024                    return;
26025                }
26026                if (record.waitingForNetwork) {
26027                    if (DEBUG_NETWORK) {
26028                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
26029                                + ", procStateSeq: " + procStateSeq);
26030                    }
26031                    record.networkStateLock.notifyAll();
26032                }
26033            }
26034        }
26035
26036        @Override
26037        public void notifyActiveVoiceInteractionServiceChanged(ComponentName component) {
26038            synchronized (ActivityManagerService.this) {
26039                mActiveVoiceInteractionServiceComponent = component;
26040            }
26041        }
26042
26043        /**
26044         * Called after virtual display Id is updated by
26045         * {@link com.android.server.vr.Vr2dDisplay} with a specific
26046         * {@param vrVr2dDisplayId}.
26047         */
26048        @Override
26049        public void setVr2dDisplayId(int vr2dDisplayId) {
26050            if (DEBUG_STACK) {
26051                Slog.d(TAG, "setVr2dDisplayId called for: " +
26052                        vr2dDisplayId);
26053            }
26054            synchronized (ActivityManagerService.this) {
26055                mVr2dDisplayId = vr2dDisplayId;
26056            }
26057        }
26058
26059        @Override
26060        public void saveANRState(String reason) {
26061            synchronized (ActivityManagerService.this) {
26062                final StringWriter sw = new StringWriter();
26063                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
26064                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
26065                if (reason != null) {
26066                    pw.println("  Reason: " + reason);
26067                }
26068                pw.println();
26069                mActivityStartController.dump(pw, "  ", null);
26070                pw.println();
26071                pw.println("-------------------------------------------------------------------------------");
26072                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
26073                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
26074                        "" /* header */);
26075                pw.println();
26076                pw.close();
26077
26078                mLastANRState = sw.toString();
26079            }
26080        }
26081
26082        @Override
26083        public void clearSavedANRState() {
26084            synchronized (ActivityManagerService.this) {
26085                mLastANRState = null;
26086            }
26087        }
26088
26089        @Override
26090        public void setFocusedActivity(IBinder token) {
26091            synchronized (ActivityManagerService.this) {
26092                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
26093                if (r == null) {
26094                    throw new IllegalArgumentException(
26095                            "setFocusedActivity: No activity record matching token=" + token);
26096                }
26097                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
26098                        r, "setFocusedActivity")) {
26099                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
26100                }
26101            }
26102        }
26103
26104        @Override
26105        public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
26106            synchronized (ActivityManagerService.this) {
26107                if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
26108                    ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
26109                    if (types == null) {
26110                        if (uid < 0) {
26111                            return;
26112                        }
26113                        types = new ArrayMap<>();
26114                        mAllowAppSwitchUids.put(userId, types);
26115                    }
26116                    if (uid < 0) {
26117                        types.remove(type);
26118                    } else {
26119                        types.put(type, uid);
26120                    }
26121                }
26122            }
26123        }
26124
26125        @Override
26126        public boolean isRuntimeRestarted() {
26127            return mSystemServiceManager.isRuntimeRestarted();
26128        }
26129
26130        @Override
26131        public boolean hasRunningActivity(int uid, @Nullable String packageName) {
26132            if (packageName == null) return false;
26133
26134            synchronized (ActivityManagerService.this) {
26135                for (int i = 0; i < mLruProcesses.size(); i++) {
26136                    final ProcessRecord processRecord = mLruProcesses.get(i);
26137                    if (processRecord.uid == uid) {
26138                        for (int j = 0; j < processRecord.activities.size(); j++) {
26139                            final ActivityRecord activityRecord = processRecord.activities.get(j);
26140                            if (packageName.equals(activityRecord.packageName)) {
26141                                return true;
26142                            }
26143                        }
26144                    }
26145                }
26146            }
26147            return false;
26148        }
26149
26150        @Override
26151        public void registerScreenObserver(ScreenObserver observer) {
26152            mScreenObservers.add(observer);
26153        }
26154
26155        @Override
26156        public boolean canStartMoreUsers() {
26157            return mUserController.canStartMoreUsers();
26158        }
26159
26160        @Override
26161        public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) {
26162            mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage);
26163        }
26164
26165        @Override
26166        public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) {
26167            mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage);
26168        }
26169
26170        @Override
26171        public int getMaxRunningUsers() {
26172            return mUserController.mMaxRunningUsers;
26173        }
26174
26175        public boolean isCallerRecents(int callingUid) {
26176            return getRecentTasks().isCallerRecents(callingUid);
26177        }
26178
26179        @Override
26180        public boolean isUidActive(int uid) {
26181            synchronized (ActivityManagerService.this) {
26182                final UidRecord uidRec = mActiveUids.get(uid);
26183                return (uidRec != null) && !uidRec.idle;
26184            }
26185        }
26186
26187        @Override
26188        public List<ProcessMemoryState> getMemoryStateForProcesses() {
26189            List<ProcessMemoryState> processMemoryStates = new ArrayList<>();
26190            synchronized (mPidsSelfLocked) {
26191                for (int i = 0, size = mPidsSelfLocked.size(); i < size; i++) {
26192                    final ProcessRecord r = mPidsSelfLocked.valueAt(i);
26193                    final int pid = r.pid;
26194                    final int uid = r.uid;
26195                    final MemoryStat memoryStat = readMemoryStatFromMemcg(uid, pid);
26196                    if (memoryStat == null) {
26197                        continue;
26198                    }
26199                    ProcessMemoryState processMemoryState =
26200                            new ProcessMemoryState(uid,
26201                                    r.processName,
26202                                    r.maxAdj,
26203                                    memoryStat.pgfault,
26204                                    memoryStat.pgmajfault,
26205                                    memoryStat.rssInBytes,
26206                                    memoryStat.cacheInBytes,
26207                                    memoryStat.swapInBytes);
26208                    processMemoryStates.add(processMemoryState);
26209                }
26210            }
26211            return processMemoryStates;
26212        }
26213    }
26214
26215    /**
26216     * Called by app main thread to wait for the network policy rules to get updated.
26217     *
26218     * @param procStateSeq The sequence number indicating the process state change that the main
26219     *                     thread is interested in.
26220     */
26221    @Override
26222    public void waitForNetworkStateUpdate(long procStateSeq) {
26223        final int callingUid = Binder.getCallingUid();
26224        if (DEBUG_NETWORK) {
26225            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
26226        }
26227        UidRecord record;
26228        synchronized (this) {
26229            record = mActiveUids.get(callingUid);
26230            if (record == null) {
26231                return;
26232            }
26233        }
26234        synchronized (record.networkStateLock) {
26235            if (record.lastDispatchedProcStateSeq < procStateSeq) {
26236                if (DEBUG_NETWORK) {
26237                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
26238                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
26239                            + " lastProcStateSeqDispatchedToObservers: "
26240                            + record.lastDispatchedProcStateSeq);
26241                }
26242                return;
26243            }
26244            if (record.curProcStateSeq > procStateSeq) {
26245                if (DEBUG_NETWORK) {
26246                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
26247                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
26248                            + ", procStateSeq: " + procStateSeq);
26249                }
26250                return;
26251            }
26252            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
26253                if (DEBUG_NETWORK) {
26254                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
26255                            + procStateSeq + ", so no need to wait. Uid: "
26256                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
26257                            + record.lastNetworkUpdatedProcStateSeq);
26258                }
26259                return;
26260            }
26261            try {
26262                if (DEBUG_NETWORK) {
26263                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
26264                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
26265                }
26266                final long startTime = SystemClock.uptimeMillis();
26267                record.waitingForNetwork = true;
26268                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
26269                record.waitingForNetwork = false;
26270                final long totalTime = SystemClock.uptimeMillis() - startTime;
26271                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
26272                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
26273                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
26274                            + procStateSeq + " UidRec: " + record
26275                            + " validateUidRec: " + mValidateUids.get(callingUid));
26276                }
26277            } catch (InterruptedException e) {
26278                Thread.currentThread().interrupt();
26279            }
26280        }
26281    }
26282
26283    public void waitForBroadcastIdle(PrintWriter pw) {
26284        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
26285        while (true) {
26286            boolean idle = true;
26287            synchronized (this) {
26288                for (BroadcastQueue queue : mBroadcastQueues) {
26289                    if (!queue.isIdle()) {
26290                        final String msg = "Waiting for queue " + queue + " to become idle...";
26291                        pw.println(msg);
26292                        pw.flush();
26293                        Slog.v(TAG, msg);
26294                        idle = false;
26295                    }
26296                }
26297            }
26298
26299            if (idle) {
26300                final String msg = "All broadcast queues are idle!";
26301                pw.println(msg);
26302                pw.flush();
26303                Slog.v(TAG, msg);
26304                return;
26305            } else {
26306                SystemClock.sleep(1000);
26307            }
26308        }
26309    }
26310
26311    /**
26312     * Return the user id of the last resumed activity.
26313     */
26314    @Override
26315    public @UserIdInt int getLastResumedActivityUserId() {
26316        enforceCallingPermission(
26317                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
26318        synchronized (this) {
26319            if (mLastResumedActivity == null) {
26320                return mUserController.getCurrentUserId();
26321            }
26322            return mLastResumedActivity.userId;
26323        }
26324    }
26325
26326    /**
26327     * Kill processes for the user with id userId and that depend on the package named packageName
26328     */
26329    @Override
26330    public void killPackageDependents(String packageName, int userId) {
26331        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
26332        if (packageName == null) {
26333            throw new NullPointerException(
26334                    "Cannot kill the dependents of a package without its name.");
26335        }
26336
26337        long callingId = Binder.clearCallingIdentity();
26338        IPackageManager pm = AppGlobals.getPackageManager();
26339        int pkgUid = -1;
26340        try {
26341            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
26342        } catch (RemoteException e) {
26343        }
26344        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
26345            throw new IllegalArgumentException(
26346                    "Cannot kill dependents of non-existing package " + packageName);
26347        }
26348        try {
26349            synchronized(this) {
26350                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
26351                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
26352                        "dep: " + packageName);
26353            }
26354        } finally {
26355            Binder.restoreCallingIdentity(callingId);
26356        }
26357    }
26358
26359    @Override
26360    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
26361            CharSequence message) throws RemoteException {
26362        if (message != null) {
26363            enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
26364                    "dismissKeyguard()");
26365        }
26366        final long callingId = Binder.clearCallingIdentity();
26367        try {
26368            mKeyguardController.dismissKeyguard(token, callback, message);
26369        } finally {
26370            Binder.restoreCallingIdentity(callingId);
26371        }
26372    }
26373
26374    @Override
26375    public int restartUserInBackground(final int userId) {
26376        return mUserController.restartUser(userId, /* foreground */ false);
26377    }
26378
26379    @Override
26380    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
26381        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
26382                "scheduleApplicationInfoChanged()");
26383
26384        synchronized (this) {
26385            final long origId = Binder.clearCallingIdentity();
26386            try {
26387                updateApplicationInfoLocked(packageNames, userId);
26388            } finally {
26389                Binder.restoreCallingIdentity(origId);
26390            }
26391        }
26392    }
26393
26394    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
26395        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
26396        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
26397            final ProcessRecord app = mLruProcesses.get(i);
26398            if (app.thread == null) {
26399                continue;
26400            }
26401
26402            if (userId != UserHandle.USER_ALL && app.userId != userId) {
26403                continue;
26404            }
26405
26406            final int packageCount = app.pkgList.size();
26407            for (int j = 0; j < packageCount; j++) {
26408                final String packageName = app.pkgList.keyAt(j);
26409                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
26410                    try {
26411                        final ApplicationInfo ai = AppGlobals.getPackageManager()
26412                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
26413                        if (ai != null) {
26414                            app.thread.scheduleApplicationInfoChanged(ai);
26415                        }
26416                    } catch (RemoteException e) {
26417                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
26418                                    packageName, app));
26419                    }
26420                }
26421            }
26422        }
26423        if (updateFrameworkRes) {
26424            // Update system server components that need to know about changed overlays. Because the
26425            // overlay is applied in ActivityThread, we need to serialize through its thread too.
26426            final Executor executor = ActivityThread.currentActivityThread().getExecutor();
26427            final DisplayManagerInternal display =
26428                    LocalServices.getService(DisplayManagerInternal.class);
26429            if (display != null) {
26430                executor.execute(display::onOverlayChanged);
26431            }
26432            if (mWindowManager != null) {
26433                executor.execute(mWindowManager::onOverlayChanged);
26434            }
26435        }
26436    }
26437
26438    /**
26439     * Attach an agent to the specified process (proces name or PID)
26440     */
26441    public void attachAgent(String process, String path) {
26442        try {
26443            synchronized (this) {
26444                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
26445                if (proc == null || proc.thread == null) {
26446                    throw new IllegalArgumentException("Unknown process: " + process);
26447                }
26448
26449                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
26450                if (!isDebuggable) {
26451                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
26452                        throw new SecurityException("Process not debuggable: " + proc);
26453                    }
26454                }
26455
26456                proc.thread.attachAgent(path);
26457            }
26458        } catch (RemoteException e) {
26459            throw new IllegalStateException("Process disappeared");
26460        }
26461    }
26462
26463    @VisibleForTesting
26464    public static class Injector {
26465        private NetworkManagementInternal mNmi;
26466
26467        public Context getContext() {
26468            return null;
26469        }
26470
26471        public AppOpsService getAppOpsService(File file, Handler handler) {
26472            return new AppOpsService(file, handler);
26473        }
26474
26475        public Handler getUiHandler(ActivityManagerService service) {
26476            return service.new UiHandler();
26477        }
26478
26479        public boolean isNetworkRestrictedForUid(int uid) {
26480            if (ensureHasNetworkManagementInternal()) {
26481                return mNmi.isNetworkRestrictedForUid(uid);
26482            }
26483            return false;
26484        }
26485
26486        private boolean ensureHasNetworkManagementInternal() {
26487            if (mNmi == null) {
26488                mNmi = LocalServices.getService(NetworkManagementInternal.class);
26489            }
26490            return mNmi != null;
26491        }
26492    }
26493
26494    @Override
26495    public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
26496            throws RemoteException {
26497        synchronized (this) {
26498            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26499            if (r == null) {
26500                return;
26501            }
26502            final long origId = Binder.clearCallingIdentity();
26503            try {
26504                r.setShowWhenLocked(showWhenLocked);
26505            } finally {
26506                Binder.restoreCallingIdentity(origId);
26507            }
26508        }
26509    }
26510
26511    @Override
26512    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
26513        synchronized (this) {
26514            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26515            if (r == null) {
26516                return;
26517            }
26518            final long origId = Binder.clearCallingIdentity();
26519            try {
26520                r.setTurnScreenOn(turnScreenOn);
26521            } finally {
26522                Binder.restoreCallingIdentity(origId);
26523            }
26524        }
26525    }
26526
26527    @Override
26528    public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition)
26529            throws RemoteException {
26530        enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
26531                "registerRemoteAnimations");
26532        definition.setCallingPid(Binder.getCallingPid());
26533        synchronized (this) {
26534            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
26535            if (r == null) {
26536                return;
26537            }
26538            final long origId = Binder.clearCallingIdentity();
26539            try {
26540                r.registerRemoteAnimations(definition);
26541            } finally {
26542                Binder.restoreCallingIdentity(origId);
26543            }
26544        }
26545    }
26546
26547    @Override
26548    public void registerRemoteAnimationForNextActivityStart(String packageName,
26549            RemoteAnimationAdapter adapter) throws RemoteException {
26550        enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
26551                "registerRemoteAnimationForNextActivityStart");
26552        synchronized (this) {
26553            final long origId = Binder.clearCallingIdentity();
26554            try {
26555                mActivityStartController.registerRemoteAnimationForNextActivityStart(packageName,
26556                        adapter);
26557            } finally {
26558                Binder.restoreCallingIdentity(origId);
26559            }
26560        }
26561    }
26562}
26563